C# 确定类型是否可转换为IDictionary<;字符串,对象>;,其中键可以是任何类型

C# 确定类型是否可转换为IDictionary<;字符串,对象>;,其中键可以是任何类型,c#,generics,reflection,type-conversion,C#,Generics,Reflection,Type Conversion,假设我们有一个实现IDictionary的类型。它叫MyStringDictionary 我正在进行一些属性/字段/方法反射,想知道该成员是否是可以转换为IDictionary的类型 我知道typeof(IDictionary).IsAssignableFrom(typeof(MyStringDictionary))将为真,因为两个泛型参数都匹配。但是,我不会直接分配给,而是将其转换为,如下所示: public class MyStringDictionary : IDictionary<

假设我们有一个实现
IDictionary
的类型。它叫
MyStringDictionary

我正在进行一些属性/字段/方法反射,想知道该成员是否是可以转换为
IDictionary
的类型

我知道
typeof(IDictionary).IsAssignableFrom(typeof(MyStringDictionary))
将为真,因为两个泛型参数都匹配。但是,我不会直接分配给
,而是将其转换为
,如下所示:

public class MyStringDictionary : IDictionary<string, string> {
   // Notice that the class itself has no generic type arguments!
}

MyStringDictionary myStringDict = GetBigDictionary();
IDictionary<string, object> genericDict = myStringDict
   .ToDictionary(kvp => kvp.Key, kvp => (object) kvp.Value);
公共类MyStringDictionary:IDictionary{ //请注意,类本身没有泛型类型参数! } MyStringDictionary MyStringDictionary=GetBigDictionary(); IDictionary genericDict=myStringDict .ToDictionary(kvp=>kvp.Key,kvp=>(对象)kvp.Value); 如何确定此转换是可能的

我想我可以看看它是否实现了
IEnumerable
,但是我又一次被一个事实所困扰,那就是我不知道
值的type参数,也不需要知道它,因为它只会被装箱到
对象

我想我可以看看它是否实现了
IEnumerable

当然,这就是路!现在,详细了解如何执行此操作:查看myObj.GetType().GetInterfaces()
的结果,并调用下面的方法。如果返回
true
,则第二个和第三个参数将设置为键的类型和值的类型

private static bool IsEnumKvp(Type t, out Type k, out Type v) {
    k = v = null;
    if (!t.IsGenericType) return false;
    var genDef = t.GetGenericTypeDefinition();
    if (genDef != typeof(IEnumerable<>)) return false;
    var itemType = t.GenericTypeArguments[0];
    if (!itemType.isGenericType) return false;
    var genItemDef = itemType.GetGenericTypeDefinition();
    if (genItemDef != typeof(KeyValuePair<,>)) return false;
    var kvpTypeArgs = genItemDef.GenericTypeArguments;
    k = kvpTypeArgs[0];
    v = kvpTypeArgs[1];
    return true;
}

请注意,此方法可能会返回多种类型的
true

Wow,-1,例如发布后0.2秒@GrantWinney我甚至没有机会看到“0”:提交时,它已经有了-1。如果是你投票支持我,谢谢你!两分钟前,我刚刚打开了
GetInterfaces
,在
GetGenericTypeDefinition
中苦苦思索,但却被
typeof(IDictionary)
卡住了。。。哦,不是
,而是
=
,因为我们处理的是
类型
对象,而不是那些类型的实例。所以你的答案可以直接用
IDictionary
来简化,而不是检查
IEnumerable
,然后再检查
KeyValuePair
,对吗?@ErikE使用
IEnumerable
更一般,因为每一本字典都是ienumerable,但不是每一本ienumerable都是字典,不同之处在于,
IDictionary
保证没有重复的
键,但
IEnumerable
没有。@ErikE这也是事实:如果知道输入是
IDictionary
,就不需要在键上设置
GroupBy
foreach (var t : MyStringDictionary.GetType().GetInterfaces()) {
    Type keyType, valType;
    if (IsEnumKvp(t, out keyType, out valType)) {
        Console.WriteLine(
            "Your class implements IEnumerable<KeyValuePair<{0},{1}>>"
        ,   keyType.FullName
        ,   valType.FullName
        );
    }
}