2012-04-18 174 views
6

是否可以将Dictionary<string, Anything>转换为一致的中间泛型类型?所以我可以将<string, string><string, bool>,<string, int>,<string, anything>全部转换为相同类型的字典?C#将Dictionary <string,AnyType>转换为Dictionary <string,Object>(涉及反射)

我对正在使用重型反射一个项目,我需要能够处理词典类型,例如:

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

上面的代码是什么,我现在已经和程序总是在失败从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; 
    } 
} 

在这种情况下,鸭子在foreach中打字很方便。

+0

这就像一个魅力,谢谢你AakashM和Gibsnag。这给了我一段时间的麻烦。 – 2012-04-18 10:27:31

+2

不需要特殊的CastDict方法,您可以使用普通的Cast ()LINQ运算符。 – 2013-07-03 03:01:34

5

这是帮助你吗?

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

因为我正在使用反射,所以我实际上无法调用ToDictionary方法。我可能能够使用更多的反射去到ToDictionary方法,但是我不确定如何将这些参数传递给它。 – 2012-04-18 09:35:32

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

我仍然收到错误“指定的转换无效”与该代码。有任何想法吗? – 2012-04-18 10:06:47

+0

'field.GetValue()'返回的对象的实际类型是什么? – AakashM 2012-04-18 10:09:48

+0

好吧,我知道它试图获得一个'Dictionary ',但这只是因为它是我的第一个测试用例。在运行时'Console.WriteLine(field.GetValue(this).GetType()。Name);'打印出'字典'2“。编辑:我刚刚跑'Console.WriteLine(field.GetValue(this));'得到了'System.Collections.Generic.Dictionary'2 [System.String,System.String]' – 2012-04-18 10:13:23

0

是有可能铸就FieldInfoDictionary如下

这是一个例子,我在我的代码

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

已经使用考虑是否铸造和object确实是必要的。我开始了这条路,偶然发现了这篇文章,然后才意识到我可以通过泛型而不是转换来实现我所需要的。例如;

class DictionaryUtils<T> 
{ 
    public static T ValueOrDefault(IDictionary<string, T> dictionary, string key) 
    { 
     return dictionary.ContainsKey(key) ? dictionary[key] : default(T); 
    } 
} 

这段代码比其他答案中显示的等效转换代码要干净得多。

相关问题