2015-11-02 80 views
0

有型號Dictionary<string,dynamic>並且想將其轉換爲Dictionary<string, MyType1>Dictionary<string, MyOtherType>如何將動態對象轉換爲指定的類型?

我已經試過

var converted = (Dictionary<string,MyType1>)model 

沒有成功嘗試

IConvertible iConv = model; var converted = iConv.ToType(typeof(MyOtherType), null); 

太多,但它不工作

異常:無法轉換System.Object要鍵入x

如何從運行時類型(動態)轉換爲衆所周知的類型?

+0

看起來像這不是一個適當的動態類型的使用。這是一種靜態類型。 –

+0

類型爲「MyType1」的字典對象中的_all_值? –

+0

@DStanley就是這樣!在檢查之後......看起來像是當一個鍵值爲空時發生異常! – Bellash

回答

3

沒有從一種字典類型到另一種字典類型的內置轉換。但是,使用Enumerable.ToDictionary,您可以輕鬆地從任何其他數據結構創建新字典。

在你的具體的例子,你可以用它作爲

var converted = model.ToDictionary(kv => kv.Key, kv => (MyType1) kv.Value); 

當然,如果你的價值觀是不實際MyType1型的,這將引發異常。如果它們不是,那麼請在(MyType1) kv.Value之前調用一些自定義轉換函數。

+0

將「as」用於與「Where(i => i.Value!= null)」結合使用時應該處理異常。 (除非涉及不可空類型,那就是) – PTwr

+0

謝謝,但我得到一個'System.InvalidCastException'類型的異常:不能從類型'System.Object'的對象類型轉換爲'MyType1'。' – Bellash

+0

@Bellash這就是我已經涵蓋在我的問題的最後一段:我只回答你問的問題。如果您還想轉換這些值,那麼問題中沒有足夠的信息來說明該轉換應該如何工作,只是需要找到某種方式來執行此轉換。 – hvd

1

我會將一個靜態構造函數放在您熟知的類型上,它接受dynamic,並從中構建衆所周知的類型。例如

public class SomeType 
{ 
    public static SomeType FromDynamic(dynamic arg) 
    { 
     return new SomeType 
     { 
       SomeProperty = arg.SomeProp 
     } 
    } 

    public int SomeProperty {get; set; } 
} 

然後,你只需要遍歷您Dictionary<string,dynamic>並建立新的對象,如:從@hvd

var dictionary = new Dictionary<string, SomeType>(); 
foreach(var item in model) 
{ 
    dictionary.Add(item.Key, SomeType.FromDynamic(item.Value)); 
} 

或者借用:

var converted = model.ToDictionary(kv => kv.Key, kv => SomeType.FromDynamic(kv.Value)); 
+1

是的,這是執行這種轉換的一種有效方式。就個人而言,在這種情況下,如果你建議的改造是簡單的我會把它內聯寫:'model.ToDictionary(KV => kv.Key,KV =>新SOMETYPE {SomeProp = kv.Value.SomeProp});' 。如果轉換更復雜,那麼我會用像你這樣的幫助方法。 – hvd

2

以下小演示適用於簡單類型: MapDynamicToDictionary測試顯示將動態轉換爲字典。 MapDictionaryToType節目做檢查類型或使用as

public class Test 
{ 
    [Fact] 
    public void MapDynamicToDictionary() 
    { 
     dynamic d = new { Nr = 1, Name = "Devon" }; 
     var dictionary = TurnObjectIntoDictionary(d); 

     Assert.Equal(2, dictionary.Keys.Count); 
    } 

    [Fact] 
    public void MapDictionaryToType() 
    { 
     dynamic d = new { Nr = 1, Name = "Devon" }; 
     var dictionary = TurnObjectIntoDictionary(d); 
     var instance = new MyType(); 
     Map(dictionary, instance); 
     Assert.Equal(instance.Nr, 1); 
     Assert.Equal(instance.Name, "Devon"); 
    } 

    public static void Map<T>(IDictionary<string, object> dictionary, T instance) 
    { 
     var attr = BindingFlags.Public | BindingFlags.Instance; 
      foreach (var prop in instance.GetType().GetProperties(attr)) 
     { 
      if (prop.CanWrite) 
      { 
       if(dictionary.ContainsKey(prop.Name)) 
       { 
        var v = Convert.ChangeType(dictionary[prop.Name], prop.PropertyType); 
        prop.SetValue(instance, v);     } 
      } 
     } 
    } 

    public static IDictionary<string, object> TurnObjectIntoDictionary(object data) 
    { 
     var attr = BindingFlags.Public | BindingFlags.Instance; 
     var dict = new Dictionary<string, object>(); 
     foreach (var prop in data.GetType().GetProperties(attr)) 
     { 
      if (prop.CanRead) 
      { 
       dict.Add(prop.Name, prop.GetValue(data, null)); 
      } 
     } 
     return dict; 
    } 
} 

class MyType 
{ 
    public int Nr { get; set; } 
    public string Name { get; set; } 
} 

能使用TypeConverter來處理更復雜的例子字典轉換爲T類型

你可以改善這一點。很好的例子:http://putridparrot.com/blog/type-conversions-in-c/

+0

這是一個絕妙的解決方案!它看起來不錯,upvoted而問題解決了@ hvd回答 – Bellash

+0

謝謝!我在地圖上添加了一個轉換,所以它應該更經常地獲得成功,並且可以鏈接到底部的其他可能性。 –

相關問題