2012-07-20 72 views
19

如何將動態對象轉換爲C#中的Dictionary<TKey, TValue>我該怎麼辦?如何將對象轉換爲C#中的Dictionary <TKey,TValue>?

public static void MyMethod(object obj) 
{ 
    if (typeof(IDictionary).IsAssignableFrom(obj.GetType())) 
    { 
     // My object is a dictionary, casting the object: 
     // (Dictionary<string, string>) obj; 
     // causes error ... 
    } 
    else 
    { 
     // My object is not a dictionary 
    } 
} 
+0

你檢查你的對象是'IDictionary'。因此,像'(IDictionary)obj'這樣的接口將會成功。儘管如此,還有許多其他的'IDictionary'比'Dictionary '更多。所以你最好測試一下你想投射的相同類型。我同意Nikhil(answerer)在這種情況下你想使用'as'。如有需要,我可以提供詳情。 – 2012-07-20 09:54:37

+0

一般在這裏考慮答案:http://stackoverflow.com/questions/3481923/in-c-sharp-convert-anonymous-type-in​​to-key-value-array(例如'RouteValueDictionary') – 2015-08-03 18:27:20

回答

16
public static KeyValuePair<object, object > Cast<K, V>(this KeyValuePair<K, V> kvp) 
    { 
     return new KeyValuePair<object, object>(kvp.Key, kvp.Value); 
    } 

    public static KeyValuePair<T, V> CastFrom<T, V>(Object obj) 
    { 
     return (KeyValuePair<T, V>) obj; 
    } 

    public static KeyValuePair<object , object > CastFrom(Object obj) 
    { 
     var type = obj.GetType(); 
     if (type.IsGenericType) 
     { 
      if (type == typeof (KeyValuePair<,>)) 
      { 
       var key = type.GetProperty("Key"); 
       var value = type.GetProperty("Value"); 
       var keyObj = key.GetValue(obj, null); 
       var valueObj = value.GetValue(obj, null); 
       return new KeyValuePair<object, object>(keyObj, valueObj); 
      } 
     } 
     throw new ArgumentException(" ### -> public static KeyValuePair<object , object > CastFrom(Object obj) : Error : obj argument must be KeyValuePair<,>"); 
    } 

從OP:

而不是轉換我的整個字典,我決定保持我的目標 動態整個時間。當我用foreach訪問我的 字典的鍵和值時,我使用foreach( obj.Keys中的動態鍵),並簡單地將鍵和值轉換爲字符串。

4

這應該工作:

數字,字符串,日期等:

public static void MyMethod(object obj) 
    { 
     if (typeof(IDictionary).IsAssignableFrom(obj.GetType())) 
     { 
      IDictionary idict = (IDictionary)obj; 

      Dictionary<string, string> newDict = new Dictionary<string, string>(); 
      foreach (object key in idict.Keys) 
      { 
       newDict.Add(key.ToString(), idict[key].ToString()); 
      } 
     } 
     else 
     { 
      // My object is not a dictionary 
     } 
    } 

如果你的字典中還包含一些其他對象:

public static void MyMethod(object obj) 
    { 
     if (typeof(IDictionary).IsAssignableFrom(obj.GetType())) 
     { 
      IDictionary idict = (IDictionary)obj; 
      Dictionary<string, string> newDict = new Dictionary<string, string>(); 

      foreach (object key in idict.Keys) 
      { 
       newDict.Add(objToString(key), objToString(idict[key])); 
      } 
     } 
     else 
     { 
      // My object is not a dictionary 
     } 
    } 

    private static string objToString(object obj) 
    { 
     string str = ""; 
     if (obj.GetType().FullName == "System.String") 
     { 
      str = (string)obj; 
     } 
     else if (obj.GetType().FullName == "test.Testclass") 
     { 
      TestClass c = (TestClass)obj; 
      str = c.Info; 
     } 
     return str; 
    } 
+0

myTypes [0]和myTypes [1]將始終是System.Object。它可以幫助我們跟蹤字典的類型,但它似乎不起作用。我甚至需要在最後將字典轉換爲,然而thx。 – modiX 2012-07-20 11:09:33

+0

這是我的錯,得到你需要用idictionary做的類型 'IDictionary idict =(IDictionary)obj; Type [] myTypes = idict.GetType()。GetGenericArguments(); Dictionary dict = idict.Cast ().ToDictionary(entry => entry.Key,entry => entry.Value);' – user1519979 2012-07-20 11:33:05

+0

已更新我的文章,也許有幫助 – user1519979 2012-07-20 11:48:25

-1

正如我理解它,你不確定鍵和值是什麼,但你想把它們轉換成字符串?

也許這可以工作:

public static void MyMethod(object obj) 
{ 
    var iDict = obj as IDictionary; 
    if (iDict != null) 
    { 
    var dictStrStr = iDict.Cast<DictionaryEntry>() 
     .ToDictionary(de => de.Key.ToString(), de => de.Value.ToString()); 

    // use your dictStrStr   
    } 
    else 
    { 
    // My object is not an IDictionary 
    } 
} 
+0

它會得到一個無效的轉換異常if obj是一個詞典(不包含任何空鍵或值)。它似乎有問題將數字轉換爲字符串。 – modiX 2012-07-20 10:40:08

+0

它甚至會拋出一個無效的轉換異常,如果我在該行上傳遞一個Dictionary 。然而,thx的提示,它可能接近我的解決方案。 – modiX 2012-07-20 10:54:56

+0

嗯,這也是一個醜陋的解決方案。 'obj'從哪裏來?如果我們只知道它總是某種'Dictionary <,>',那麼我們就可以使'MyMethod'成爲通用的,並且所有的都將變得簡單而美麗。 「IDictionary」的麻煩在於它也可能是一個'Hashtable'或許多其他非泛型的類型。而'foreach'對象類型甚至不一樣(我的答案沒有起作用的原因)。 – 2012-07-20 11:48:18

2

假設鍵只能是一個字符串,但值可以是任何東西試試這個

public static Dictionary<TKey, TValue> MyMethod<TKey, TValue>(object obj) 
{ 
    var stringDictionary = obj as Dictionary<TKey, TValue>; 

    if (stringDictionary!= null) 
    { 
     return stringDictionary; 
    } 
    var baseDictionary = obj as IDictionary; 

    if (baseDictionary != null) 
    { 
     var dictionary = new Dictionary<TKey, TValue>(); 
     foreach (DictionaryEntry keyValue in baseDictionary) 
     { 
      if (!(keyValue.Value is TValue)) 
      { 
       // value is not TKey. perhaps throw an exception 
       return null; 
      } 
      if (!(keyValue.Key is TKey)) 
      { 
       // value is not TValue. perhaps throw an exception 
       return null; 
      } 

      dictionary.Add((TKey)keyValue.Key, (TValue)keyValue.Value); 
     } 
     return dictionary; 
    } 
    // object is not a dictionary. perhaps throw an exception 
    return null; 

} 
29

我用這個幫手:

public static class ObjectToDictionaryHelper 
{ 
    public static IDictionary<string, object> ToDictionary(this object source) 
    { 
     return source.ToDictionary<object>(); 
    } 

    public static IDictionary<string, T> ToDictionary<T>(this object source) 
    { 
     if (source == null) 
      ThrowExceptionWhenSourceArgumentIsNull(); 

     var dictionary = new Dictionary<string, T>(); 
     foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(source)) 
      AddPropertyToDictionary<T>(property, source, dictionary); 
     return dictionary; 
    } 

    private static void AddPropertyToDictionary<T>(PropertyDescriptor property, object source, Dictionary<string, T> dictionary) 
    { 
     object value = property.GetValue(source); 
     if (IsOfType<T>(value)) 
      dictionary.Add(property.Name, (T)value); 
    } 

    private static bool IsOfType<T>(object value) 
    { 
     return value is T; 
    } 

    private static void ThrowExceptionWhenSourceArgumentIsNull() 
    { 
     throw new ArgumentNullException("source", "Unable to convert object to a dictionary. The source object is null."); 
    } 
} 

的使用只是調用.ToDictionary()對象

希望它可以幫助上。

-1
object parsedData = se.Deserialize(reader); 
System.Collections.IEnumerable stksEnum = parsedData as System.Collections.IEnumerable; 

然後將能夠枚舉它!

2
public static void MyMethod(object obj){ 
    Dictionary<string, string> dicEditdata = data as Dictionary<string, string>; 
    string abc=dicEditdata["id"].ToString();} 

假設--- 如果你把光標放在對象(obj),同時調試和 如果你得到的值的對象{['id':'ID1003']} 那麼你可以使用該值作爲

string abc=dicEditdata["id"].ToString(); 
-1

簡單的方法:

public IDictionary<T, V> toDictionary<T, V>(Object objAttached) 
{ 
    var dicCurrent = new Dictionary<T, V>(); 
    foreach (DictionaryEntry dicData in (objAttached as IDictionary)) 
    { 
     dicCurrent.Add((T)dicData.Key, (V)dicData.Value); 
    } 
    return dicCurrent; 
} 
+0

問題不在於「如何將IDictionary對象轉換爲IDictionary ?」。問題是「如何將Object對象轉換爲IDictionary ?」。 – dizel3d 2017-02-03 11:38:28

0

您可以創建一個通用的擴展方法,然後使用它像在對象上:

public static class Extensions 
{ 
    public static KeyValuePair<TKey, TValue> ToKeyValuePair<TKey, TValue>(this Object obj) 
    { 
     // if obj is null throws exception 
     Contract.Requires(obj != null); 

     // gets the type of the obj parameter 
     var type = obj.GetType(); 
     // checks if obj is of type KeyValuePair 
     if (type.IsGenericType && type == typeof(KeyValuePair<TKey, TValue>)) 
     { 

      return new KeyValuePair<TKey, TValue>(
                (TKey)type.GetProperty("Key").GetValue(obj, null), 
                (TValue)type.GetProperty("Value").GetValue(obj, null) 
               ); 

     } 
     // if obj type does not match KeyValuePair throw exception 
     throw new ArgumentException($"obj argument must be of type KeyValuePair<{typeof(TKey).FullName},{typeof(TValue).FullName}>"); 
} 

和用法是這樣的:

KeyValuePair<string,long> kvp = obj.ToKeyValuePair<string,long>(); 
3

以上答案都很酷。我發現json很容易序列化對象並反序列化爲字典。

var json = JsonConvert.SerializeObject(obj); 
var dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(json); 

我不知道性能如何影響,但這樣更容易閱讀。你也可以把它包裝在一個函數中。

public static Dictionary<string, TValue> ToDictionary<TValue>(object obj) 
{  
    var json = JsonConvert.SerializeObject(obj); 
    var dictionary = JsonConvert.DeserializeObject<Dictionary<string, TValue>>(json); 
    return dictionary; 
} 

使用像這樣:

var obj = new { foo = 12345, boo = true }; 
var dictionary = ToDictionary<string>(obj); 
0

我用這個簡單的方法:

public Dictionary<string, string> objToDict(XYZ.ObjectCollection objs) { 
    var dict = new Dictionary<string, string>(); 
    foreach (KeyValuePair<string, string> each in objs){ 
     dict.Add(each.Key, each.Value); 
    } 
    return dict; 
} 
相關問題