将运行时字典<k,v =“”>作为泛型类型参数转换为正确的编译时类型</k,>

时间:2014-01-13 11:58:57

标签: c#

考虑一下:

public void ReadEachItemInTheDictionary<V>(V value)
{
  // I know that value is a dictionary
  // where the key and value are scalars
  // or primitive types or value types
  if (value.GetType().IsGenericType && 
       value.GetType().GetGenericTypeDefinition() == 
              typeof(Dictionary<,>))
  {
    // I know the System.Type of each type
    // argument of the dictionary

    var keyType = value.GetType().GetGenericArguments()[0];

    var valueType = value.GetType().GetGenericArguments()[1];

    // Now, I want to do something like this:
    foreach(var keyValuePair in value)
    {
        // However, since at compile-time, there
        // is no guarantee for the compiler that 
        // value is indeed an IEnumerable<KeyValuePair<,>>
        // that code won't work, obviously.

        // I want to basically get a handle on the
        // data


        // I feel horrible. I should know this. And
        // there was a time I did. Just feeling ashamed now.
    }
  }
}

更新

看看我收到的两个答案,我不得不再次强调我的问题:

我只有字典的keyvalue的类型参数名称。哦,我突然得到了答案。等等,我发布了它。

再次更新

不,等等。我在做什么?仍然没有解决。

4 个答案:

答案 0 :(得分:4)

这闻起来像滥用仿制药,但无论如何:

将foreach循环放入一个具有适当泛型类型参数的单独方法中(可能与字典相同)。

static void Read<TKey, TValue(Dictionary<TKey, TValue> dict) {
 foreach(var keyValuePair in dict) { }
}

在该方法中,您可以像平常一样使用该词典。

使用反射(MakeGenericMethod)调用该方法,或者像这样:

Read((dynamic)value);

您不能将所有字典处理代码静态输入。只有通话必须是动态的。

答案 1 :(得分:3)

通用Dictionary<>实现非通用IDictionary,因此您可以投射和使用它:

var dict = value as IDictionary;
foreach (var item in dict)
{
    var entry = (DictionaryEntry)item;
    // use entry.Key and entry.Value
}

答案 2 :(得分:1)

我会建议一种与类型系统更合作的方法。你的问题实际上归结为KeyValuePair<TKey, TValue>没有实现非泛型接口的事实,否则你可以简单地将字典转换为IEnumerable<NonGenericKeyValuePair>。但是,Dictionary<TKey, TValue>确实支持非通用IDictionary,它具有单独的KeysValues个集合,因此您可以执行此操作:

var dict = (IDictionary)input;
for each (var key in dict.Keys) {
    var value = dict[key];
}

答案 3 :(得分:0)