2009-08-02 14 views
3

J'ai un objet qui est un dictionnaire d'un type inconnu (ie je ne connais pas le type pour la clé et la valeur)Comment puis-je récupérer toutes les KeyValuePairs contenues dans un Dictonary <?,?>?

Je veux récupérer toutes ses valeurs pour que je puisse y accéder par indice.

donc ce que je veux faire est quelque chose comme ça:

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

Cependant, comme prévu, le moteur d'exécution ne me laisse pas à un objet jeté Dictionnaire <, object>.

Existe-t-il un moyen de faire cela dans .net 3.0? (? Par exemple en utilisant la réflexion)

+0

Hey Brann, nous en dire un peu plus sur l'objet? Quel type est-ce exactement? Quelles méthodes et propriétés a-t-il? –

+0

@Oren: C'est un dictionnaire – Brann

+0

Etes-vous certain que l'objet que vous essayez de lancer en tant que Dictionnaire <,> est vraiment un objet Dictionnaire? –

Répondre

5

You can't cast obj à un Dictionary<object, object> parce qu'il est pas un Dictionary<object, object>. Oui, ses clés et ses valeurs dérivent de object, et peuvent donc être converties en object. Mais vous ne pouvez pas lancer de types génériques en C# car ils ne sont pas covariants. Même si T dérive de object, List<T> ne dérive pas de List<object>.

Tenir compte de cette méthode:

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

Si vous pouviez jeter List<int> à List<object>, vous pourriez passer un List<int> à cette méthode et il se transformerait en quelque chose d'autre.

Cela va changer lorsque les génériques covariants sont introduits dans C# 4.0. This article est une très bonne explication des problèmes impliqués.

Mais pour résoudre votre problème réel, cela fera l'affaire:

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

Pour info; La covariance C# 4.0 ne fera aucune différence avec 'List ' (ni 'IList ', ni aucun des types de dictionnaire); seulement des choses plus simples comme 'IEnumerable ' et les types 'Func <...>'; http://marcgravell.blogspot.com/2009/02/what-c-40-covariance-doesn-do.html –

+0

Droit. L'ajout de cette fonctionnalité à la langue ne permet pas de lancer une classe de collection, ce qui est même possible. La liste est à la fois covariante et contravariante; T est utilisé à la fois dans une position de sortie (par exemple, l'indexeur renvoie un objet de type T) et dans une position d'entrée (par exemple, Add (élément T)). –

15

Depuis Dictionary<,> met en œuvre IDictionary (non génériques), juste itérer que:

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

Je crois que le problème est en fait avec la coulée d'un objet à un dictionnaire <,> par opposition à l'itération de ses entrées. –

+0

@tsvanharen - Cette approche résout ce problème. – codekaizen

+0

+1: IDictionary (non générique) était exactement ce dont j'avais besoin pour recopier des objets de collection inconnus. IList également utilisé non-générique pour les listes, fonctionne un régal. Merci –

0

peut-être:

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

Questions connexes