2013-01-05 165 views
0

我正在對我的問題進行重新說明,以便更具體並針對實際的關注領域。將未知類型轉換爲另一個類型的泛型

我有許多不同的類,這是我的實體,我不是那個類的。當我想將實體升級到新實體時,我想將這些屬性轉換爲新的屬性(我發現它們不區分大小寫)。

我的問題很簡單,但可能需要一個複雜的答案。

當我遇到一個不同於升級版本的類型時,我需要將舊版本升級到新版本。這兩種類型都是未知的,因爲那是重點。我可以通過任何兩個我想要的類,它將傳遞屬性很好。

所以,如果我有兩類:

public class OldEntity 
{ 
    public string Name {get;set;} 
    public int SomeProperty {get;set;} 
} 

public class NewEntity 
{ 
    public string Name {get;set;} 
    public string SomeProperty {get;set;} 
} 

所以,我需要找出舊型的SomeProperty,然後將其轉換爲新類型的SomeProperty

我想我能做到,我希望有那麼這是一種更通用的方法:

switch (typeof(SomeProperty.Value.GetType()) 
{ 
    case typeof(Int): 
     return Int.Parse(OldSomeProperty.Value); 
} 

很顯然,這是非常原始的代碼,但你得到的要點。

請能有人給我這樣做,還有一件事是更寬泛的方式,我有AutoMapper下載,它不註釋,這樣如果有人能告訴我在哪裏,它是怎麼做的,這將是一個很好的答案好。

所以我試着簡單的解決辦法,不是很通用:

public static object ConvertSourceObjectDestinationObject(object source, object destination) 
{ 
    // get the string representation of the source object 
    var strRepresentation = source.ToString(); 
    // find out the destinations type 
    var originalCode = AssemblyCode(destination.GetType().Assembly.ToString()); 

    // search for a match then convert the source object to the new destination objects type 
    switch (originalCode) 
    { 
     case 0: 
      return strRepresentation; 
     case 1: 
      return int.Parse(strRepresentation); 
     case 2: 
      return decimal.Parse(strRepresentation); 
     case 3: 
      return DateTime.Parse(strRepresentation); 
     case 4: 
      return byte.Parse(strRepresentation); 
     case 5: 
      return float.Parse(strRepresentation); 
     case 6: 
      return Guid.Parse(strRepresentation); 
     default: 
      return strRepresentation; 
    } 
} 

public static int AssemblyCode(string assemblyString) 
{ 
    if (assemblyString.Equals(typeof(string).Assembly.ToString())) 
     return 0; 

    if (assemblyString.Equals(typeof(int).Assembly.ToString())) 
     return 1; 

    if (assemblyString.Equals(typeof(decimal).Assembly.ToString())) 
     return 2; 

    if (assemblyString.Equals(typeof(DateTime).Assembly.ToString())) 
     return 3; 

    if (assemblyString.Equals(typeof(byte).Assembly.ToString())) 
     return 4; 

    if (assemblyString.Equals(typeof(float).Assembly.ToString())) 
     return 5; 

    if (assemblyString.Equals(typeof(Guid).Assembly.ToString())) 
     return 6; 

    return -1; 
} 

我做了一個新的它做了的TryParse而不是解析,使之更加安全的,但你得到的要點。它不是我所知道的優雅,但是如果有人能夠用我的方式將未知物體投射到其他未知物體上,那將會很棒。

+0

我不明白你的問題。 'GetValue'和'SetValue'在'object'上操作,那麼爲什麼你需要投射?如果不是使用帶'x'和'y'的抽象例子,而是顯示特定的行,導致您的方法出現問題,這可能會有所幫助。 –

+0

該方法出錯了。我只傳遞對象,然後通過關於投射的錯誤! –

+0

對於光顧的語氣我感到抱歉。我檢查了你的個人資料,你絕對正確。 –

回答

1

通用系統需要一些幫助,知道什麼類型的,有時,這與類型約束(ref)照顧的仿製藥,這可以幫助你與你的榜樣。

如果您知道您想要投射的泛型類型始終是某個基類,請使用where T:<base class name>約束。

如果轉換異常是由於它不能識別未繼承的類型之間的隱式轉換,則反射可能是您唯一的選擇。

0

您使用通用約束新

public static void SetEntityValue<TEntity>(ref TEntity entityToTransform, PropertyHelper entityProperty) where TEntity: new 

,這將允許你這樣做:

TEntity ent = new TEntity() 

或(和我認爲這是你想要的)使用同樣的事情

(通用約束),你可以告訴方法泛型參數類型是從哪裏來的。

public static void SetEntityValue<TEntity>(ref TEntity entityToTransform, PropertyHelper entityProperty) where TEntity: x 

這基本上意味着你可以告訴編譯器泛型類型必須是什麼(這意味着你的方法強制轉換纔有意義和編譯

如果你不知道類型是什麼,那麼你可能到使用對象上反射...

+0

我沒有試圖實例化對象,我想將其屬性值轉換爲另一個對象屬性值! –

+0

我想我會使用反射。 –

+0

閱讀你的其他評論,你可以使泛型方法只接受從特定接口派生的類型(它具有所有需要和共享的屬性訪問器)並添加該接口的通用約束@ No1_Melman –

相關問題