webentwicklung-frage-antwort-db.com.de

Wie konvertiere ich ein Objekt in C # zu Dictionary <TKey, TValue>?

Wie konvertiere ich ein dynamisches Objekt in Dictionary<TKey, TValue> in C # Was kann ich tun?

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
    }
}
25
modiX
    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<,>");
    }

Aus dem OP: 

Anstatt mein gesamtes Wörterbuch zu konvertieren, entschied ich mich, mein obj die ganze Zeit dynamisch. Wenn ich auf die Schlüssel und Werte meines Wörterbuch mit einem foreach später verwende ich foreach (dynamischer Schlüssel in Obj.Keys) und konvertiere die Schlüssel und Werte einfach in Strings.

17
cuongvn_it

Ich benutze diesen Helfer:

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.");
    }
}

die Verwendung ist nur, um .ToDictionary() für ein Objekt aufzurufen

Ich hoffe es hilft.

37
d.popov

Die obigen Antworten sind alle cool. Ich fand es einfach, das Objekt json zu serialisieren und als Wörterbuch zu deserialisieren.

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

Ich weiß nicht, wie die Performance beeinflusst wird, aber das ist viel einfacher zu lesen. Sie können es auch in eine Funktion einschließen.

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

Verwenden Sie wie folgt:

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

das sollte funktionieren:

für Zahlen, Zeichenfolgen, Datum usw.:

    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
        }
    }

wenn Ihr Wörterbuch auch andere Objekte enthält:

    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;
    }
4
user1519979
   public static void MyMethod(object obj){
   Dictionary<string, string> dicEditdata = data as Dictionary<string, string>;
   string abc=dicEditdata["id"].ToString();} 

angenommen, --- Wenn Sie den Cursor beim Debuggen über dem Objekt (obj) platzieren und , wenn Sie ein Objekt mit dem Wert {['id':'ID1003']} erhalten, können Sie den Wert als verwenden 

string abc=dicEditdata["id"].ToString(); 
3
Lijin Durairaj

Angenommen, key kann nur eine Zeichenfolge sein, value kann jedoch alles sein

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;

}
2
Simon

Ich verwende diese einfache Methode:

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;
}
0
T.Todua

Sie können eine generische Erweiterungsmethode erstellen und diese dann für das Objekt verwenden, z.

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}>");   
 }

und Verwendung wäre wie:

KeyValuePair<string,long> kvp = obj.ToKeyValuePair<string,long>();
0
Ehsan Sajjad

Dieser Code funktioniert sicher, um Object in Dictionary zu konvertieren (unter der Voraussetzung, dass das Quellobjekt aus einem Dictionary stammt):

    private static Dictionary<TKey, TValue> ObjectToDictionary<TKey, TValue>(object source)
    {
        Dictionary<TKey, TValue> result = new Dictionary<TKey, TValue>();

        TKey[] keys = { };
        TValue[] values = { };

        bool outLoopingKeys = false, outLoopingValues = false;

        foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(source))
        {
            object value = property.GetValue(source);
            if (value is Dictionary<TKey, TValue>.KeyCollection)
            {
                keys = ((Dictionary<TKey, TValue>.KeyCollection)value).ToArray();
                outLoopingKeys = true;
            }
            if (value is Dictionary<TKey, TValue>.ValueCollection)
            {
                values = ((Dictionary<TKey, TValue>.ValueCollection)value).ToArray();
                outLoopingValues = true;
            }
            if(outLoopingKeys & outLoopingValues)
            {
                break;
            }
        }

        for (int i = 0; i < keys.Length; i++)
        {
            result.Add(keys[i], values[i]);
        }

        return result;
    }
0