考虑一下:
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.
}
}
}
更新
看看我收到的两个答案,我不得不再次强调我的问题:
我只有字典的key
和value
的类型参数名称。哦,我突然得到了答案。等等,我发布了它。
再次更新
不,等等。我在做什么?仍然没有解决。答案 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,它具有单独的Keys
和Values
个集合,因此您可以执行此操作:
var dict = (IDictionary)input;
for each (var key in dict.Keys) {
var value = dict[key];
}
答案 3 :(得分:0)
多么忘记我。 MakeGenericType
是我的朋友。
http://msdn.microsoft.com/en-us/library/system.type.makegenerictype%28v=vs.110%29.aspx