2009-08-02 2 views
3

Ich habe ein Objekt, das ein Dictionary eines unbekannten Typs ist (dh ich kenne den Typ für den Schlüssel und den Wert nicht)Wie kann ich alle in einem Dictonary <?,?> enthaltenen KeyValuePairs abrufen?

Ich möchte alle seine Werte abrufen, damit ich auf diese zugreifen kann Index.

Also, was ich tun möchte, ist so etwas wie die:

Dictionary<object, object> d = (Dictionary<object, object>)obj; // cast error 
l = new List<KeyValuePair<object,object>>(); 
foreach (KeyValuePair<object, object> k in d) 
    l.Add(new KeyValuePair<object,object>(k.Key, k.Value)); 

jedoch, wie erwartet, die Laufzeit wird mich nicht auf ein Wörterbuch < Objekt werfen lassen, object>.

Gibt es eine Möglichkeit, dies in .net 3.0 zu tun? (? Zum Beispiel unter Verwendung von Reflexion)

+0

Hey Brann, erzählen Sie uns ein wenig mehr über das Objekt? Welcher Typ ist es genau? Welche Methoden und Eigenschaften hat es? –

+0

@Oren: Es ist ein Wörterbuch – Brann

+0

Sind Sie sicher, dass das Objekt, das Sie versuchen, als ein Wörterbuch <,> zu werfen, wirklich ein Dictionary-Objekt ist? –

Antwort

5

You can't cast obj zu einem Dictionary<object, object>, weil es keine Dictionary<object, object> ist. Ja, seine Schlüssel und Werte stammen von object und können daher in object umgewandelt werden. Sie können jedoch keine generischen Typen in C# darstellen, da sie nicht kovariant sind. Obwohl sich T von object ableitet, leitet sich List<T> nicht von List<object> ab.

Betrachten Sie diese Methode:

void ModifyList<List<object> list) 
{ 
    for (int i=0; i<list.Count; i++) 
    { 
     list[i] = list[i].ToString(); 
    } 
} 

Wenn Sie List<int> zu List<object> werfen könnte man eine List<int> dieser Methode passieren könnte und es würde in etwas anderes verwandeln.

Dies wird sich ändern, wenn in C# 4.0 kovariante Generika eingeführt werden. This article ist eine ziemlich gute Erklärung für die damit verbundenen Probleme.

Aber Ihr eigentliches Problem zu lösen, wird dies den Trick:

List<KeyValuePair<object, object>> list = d.AsEnumerable() 
    .Select(x => new KeyValuePair<object, object>(x.Key, x.Value)) 
    .ToList(); 
+2

Für Info; Die C# 4.0-Kovarianz wird keinen Unterschied zu "Liste " (noch zu "IList ", noch irgendeinem der Dictionary-Typen) machen; nur einfachere Dinge wie 'IEnumerable ' und die 'Func <...>' Arten; http://marcgravell.blogspot.com/2009/02/what-c-40-covariance-doesn-do.html –

+0

Richtig. Wenn diese Funktion der Sprache hinzugefügt wird, ist das Erstellen von Auflistungsklassen nicht sinnvoll oder sogar möglich. Liste ist sowohl kovariant als auch kontravariant; T wird sowohl in einer Ausgabeposition (z. B. der Indexer gibt ein Objekt vom Typ T zurück) als auch in einer Eingabeposition (z. B. Add (T-Punkt)) verwendet. –

15

Da Dictionary<,> implementiert IDictionary (non-generic), iterieren nur das:

IDictionary data = ... 
    foreach (DictionaryEntry de in data) 
    { 
     Console.WriteLine(de.Key + ": " + de.Value); 
    } 
+0

Ich glaube, das Problem besteht darin, ein Objekt auf ein Dictionary <,> zu werfen, anstatt seine Einträge zu iterieren. –

+0

@tsvanharen - Dieser Ansatz löst dieses Problem. – codekaizen

+0

+1: IDictionary (nicht-generisch) war genau das, was ich benötigte, um unbekannte Sammlungsobjekte zu rekrutieren. Auch verwendet nicht-generische IList für Listen, funktioniert ein Leckerbissen. Danke –

0

vielleicht:

 
foreach (object key in d.keys) 
{ 
l.Add(new KeyValuePair(key, d[key]); 
} 

Verwandte Themen