2009-08-02 1 views
3

У меня есть объект, который является Словарем неизвестного типа (т. Е. Я не знаю типа для ключа и значения)Как я могу получить все KeyValuePairs, содержащиеся в Dictonary <?,?>?

Я хочу получить все его значения, чтобы получить доступ к ним по индекс.

Так что я хочу сделать что-то вроде этого:

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

Однако, как и следовало ожидать, среда выполнения не позволит мне бросить в словарь < объекта, объект>.

Есть ли способ сделать это в .net 3.0? (? Например, с помощью отражения)

+0

Эй Брэнн, рассказать нам немного больше об объекте? Какого типа это точно? Какие у него методы и свойства? –

+0

@Oren: Это словарь – Brann

+0

Вы уверены, что объект, который вы пытаетесь использовать в качестве словаря <,>, действительно является объектом словаря? –

ответ

5

You can't cast obj к Dictionary<object, object>, потому что это не Dictionary<object, object>. Да, его ключи и значения производятся от object и могут быть отброшены до object. Но вы не можете вводить общие типы в C#, потому что они не ковариантны. Хотя T происходит от object, List<T> не происходит от List<object>.

Рассмотрим этот метод:

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

Если бы вы могли бросить List<int> к List<object>, вы могли бы пройти List<int> к этому методу и она превратится в нечто другое.

Это изменится, когда в C# 4.0 будут введены ковариантные дженерики. This article - довольно хорошее объяснение связанных с этим проблем.

Но чтобы решить вашу проблему реально, это будет делать трюк:

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

Для информации; Covariance C# 4.0 не имеет никакого значения для 'List ' (а не 'IList ' или ни один из типов словарей); только более простые вещи, такие как 'IEnumerable ' и 'Func <...>' types; http://marcgravell.blogspot.com/2009/02/what-c-40-covariance-doesn-do.html –

+0

Право. Добавление этой функции к языку не дает отличным представлениям или даже возможно. Список является ковариантным и контравариантным; T используется как в выходной позиции (например, индексщик возвращает объект типа T), так и входную позицию (например, Add (T item)). –

15

Так как Dictionary<,> орудия IDictionary (нетипичных), просто итерацию, что:

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

Я полагаю, что проблема заключается в том, что накладывать объект на словарь <,>, в отличие от повторения его записей. –

+0

@tsvanharen - Этот подход решает эту проблему. – codekaizen

+0

+1: IDictionary (non-generic) был именно тем, что мне нужно было для восстановления неизвестных объектов коллекции. Также используется не-общий IList для списков, работает. Thanks –

0

возможно:

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

Смежные вопросы