2012-04-18 11 views
6

Можно ли сделать согласованным промежуточным общим типом? Так что я смог бы отличить <string, string>, <string, bool>, <string, int>, <string, anything> все в том же типе словаря?C# cast Словарь <string, AnyType> в словарь <string, Object> (Вовлечение отражения)

Я работаю над проектом, который использует тяжелое отражение, и мне нужно, чтобы иметь возможность обрабатывать СЛОВАРЬ типы, как, например:

FieldInfo field = this.GetType().GetField(fieldName); 
Dictionary<string, Object> dict = (Dictionary<string, Object>)field.GetValue(this); 

Приведенный выше код является то, что я в настоящее время, и программа всегда терпит неудачу на cast from field.GetValue к общему Dictionary<string, Object>.

Есть ли способ сделать это? Или мне просто нужно выяснить другой способ обработки этих словарей?

Любая помощь была бы принята с благодарностью.

ответ

8

После AakashM's answer, Кастинг, похоже, не играет в мяч. Вы можете обойти это с помощью небольшого вспомогательного метода, хотя:

IDictionary dictionary = (IDictionary)field.GetValue(this); 
Dictionary<string, object> newDictionary = CastDict(dictionary) 
              .ToDictionary(entry => (string)entry.Key, 
                 entry => entry.Value); 

private IEnumerable<DictionaryEntry> CastDict(IDictionary dictionary) 
{ 
    foreach (DictionaryEntry entry in dictionary) 
    { 
     yield return entry; 
    } 
} 

Уток набрав в Еогеаспе удобно в данном случае.

+0

Это работало как шарм, Спасибо вам и AakashM, и Gibsnag. Это немного помогло мне. –

+2

Нет необходимости в специальном методе CastDict, вы можете просто использовать обычный оператор LINK () LINQ. –

5

Помогло ли вам это?

Dictionary<a, b> output = 
    input.ToDictionary(item => item.Key, item => (SomeType)item.Value); 
+0

Я не могу назвать метод ToDictionary, так как я использую отражение. Я мог бы использовать больше отражений, чтобы перейти к методу ToDictionary, но тогда я был бы не уверен в том, как передавать в него такие параметры. –

8

Даже если вы могли бы найти какой-нибудь способ, чтобы выразить это, было бы неправильно, что нужно сделать - это не правда, что Dictionary<string, bool>являетсяDictionary<string, object>, так что мы определенно не хотим бросить , Подумайте, что если мы с можем сделать, мы можем попробовать поставить string в качестве значения, которое явно не подходит!

Что мы можем сделать, однако, отливают в нетипичных IDictionary (который все Dictionary<,> реализуем), а затем использовать, чтобы построить новыйDictionary<string, object> с теми же значениями:

FieldInfo field = this.GetType().GetField(fieldName); 
IDictionary dictionary = (IDictionary)field.GetValue(this); 
Dictionary<string, object> newDictionary = 
    dictionary 
    .Cast<dynamic>() 
    .ToDictionary(entry => (string)entry.Key, 
        entry => entry.Value); 

(обратите внимание, что вы не можете использовать .Cast<DictionaryEntry> здесь the reasons discussed here. Если вы предварительно C# 4, и поэтому не имеют dynamic, вы должны сделать перечисление вручную, как Gibsnag's answer does)

+0

Я все еще получаю сообщение об ошибке «Указанный приказ недействителен» с этим кодом. Есть идеи? –

+0

Каков фактический тип объекта, возвращаемого 'field.GetValue()'? – AakashM

+0

Ну, я знаю, что он пытается получить «Словарь <строка, строка>», но это только потому, что это мой первый тестовый пример. Во время выполнения 'Console.WriteLine (field.GetValue (this) .GetType(). Name);' печатает "Dictionary'2". Изменить: я просто запускал 'Console.WriteLine (field.GetValue (this));' и получил 'System.Collections.Generic.Dictionary'2 [System.String, System.String]' –

0

Да Можно бросить FieldInfo к Dictionary ниже

Это один пример, я использовал в своем коде

Dictionary<string, string> 
       GetTheDict = FilesAndPaths.GetType() 
          .GetFields() 
          .Where(f => f.Name.Equals(pLoadFile)) 
          .Select(f => (Dictionary<string, string>)f.GetValue(FilesAndPaths)) 
          .Single(); 
0

Рассмотрим отливки и из object действительно ли это необходимо. Я начал этот путь и наткнулся на эту статью, прежде чем осознал, что могу добиться того, что мне нужно, вместо генерирования, а не с помощью дженериков. Например;

Этот бит кода намного чище и будет быстрее, чем эквивалентный код преобразования, показанный в других ответах.

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