如何在C#中将对象转换为Dictionary <TKey,TValue>?

mod*_*diX 32 .net c# dictionary object

如何将动态对象转换为Dictionary<TKey, TValue>C#我该怎么办?

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
    }
}
Run Code Online (Sandbox Code Playgroud)

chr*_*989 47

以上答案都很酷.我发现json序列化对象很容易并反序列化为字典.

var json = JsonConvert.SerializeObject(obj);
var dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
Run Code Online (Sandbox Code Playgroud)

我不知道性能是如何影响的,但这更容易阅读.你也可以将它包装在一个函数中.

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

使用如下:

var obj = new { foo = 12345, boo = true };
var dictionary = ToDictionary<string>(obj);
Run Code Online (Sandbox Code Playgroud)

  • 我采用了这种方法,但发现它非常慢,所以请谨慎使用!当调用数百本词典时,我的应用程序速度变得非常缓慢。 (3认同)
  • 不适用于嵌套对象 (3认同)
  • 伟大的横向思维!然后我会把它放在一个扩展中:``` public static class Extensions { public static IDictionary&lt;string, object&gt; ToDictionary( this object o) { var j = JsonConvert.SerializeObject(o); var value = JsonConvert .DeserializeObject&lt;IDictionary&lt;string, object&gt;&gt;(j); 返回值;} }``` (2认同)
  • 请记住,此方法会将 Int32 转换为 Int64,因为 JSON 没有足够强大的类型,并且基本上对所有内容都有“数字” (2认同)

d.p*_*pov 40

我用这个助手:

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.");
    }
}
Run Code Online (Sandbox Code Playgroud)

用法只是调用.ToDictionary()一个对象

希望能帮助到你.


小智 21

    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<,>");
    }
Run Code Online (Sandbox Code Playgroud)

来自OP:

而不是转换我的整个词典,我决定保持我的obj动态一直.当我使用foreach访问我的Dictionary的键和值时,我使用foreach(obj.Keys中的动态键)并简单地将键和值转换为字符串.


mce*_*mmy 12

如果您不介意 LINQ 表达式;

public static Dictionary<string, object> ConvertFromObjectToDictionary(object arg)
{
     return arg.GetType().GetProperties().ToDictionary(property => property.Name, property => property.GetValue(arg));
}
Run Code Online (Sandbox Code Playgroud)


Big*_*toe 9

另一种选择是使用 NewtonSoft.JSON。

var dictionary = JObject.FromObject(anObject).ToObject<Dictionary<string, object>>();
Run Code Online (Sandbox Code Playgroud)


use*_*979 7

这应该有效:

对于数字、字符串、日期等:

    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
        }
    }
Run Code Online (Sandbox Code Playgroud)

如果您的字典还包含一些其他对象:

    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;
    }
Run Code Online (Sandbox Code Playgroud)