示例:
class Base<T>{}
class Child<T> : Base<T>{}
typeof( Base<> ).IsGenericTypeDefinition; // == true ie. parameterless
typeof( Child<> ).BaseType.IsGenericTypeDefinition; // == false wtf???
// Eventually
typeof( Base<> ) != typeof( Child<> ).BaseType;
由于此功能typeof( Child<> ).IsSubclassOf( typeof( Base<> ) )
不起作用。
答案 0 :(得分:2)
我已经阅读了文档here,并解释了IsGenericType
和IsGenericTypeDefinition
之间的区别。
您的BaseType
属于此类:开放构造类型
ContainsGenericParameters属性为 true 。
示例是具有未分配的类型参数 a的泛型类型 嵌套在通用类型定义 中的类型 构造类型,或具有类型参数的泛型类型 ContainsGenericParameters属性为true。
无法创建开放构造类型的实例。
因此,为了使类型定义通用,您必须能够从中创建一个实例。但是在这种情况下,BaseType
是一个开放的构造类型,并且绑定到它的继承者:Child<T>
,如果创建一个Child<int>
,则基数变为Base<int>
,而不是反之亦然。
因此,您不能直接通过调用BaseType
从MakeGenericType
创建泛型类型实例,因为它的类型参数是在继承者类Child<T>
中声明的。
答案 1 :(得分:1)
我在书Professional .NET 2.0 Generics
的{{1}}部分中找到了一些信息。
继承的类型间接绑定到子类的TValue参数。
我做了一些简单的测试:
Reflection and Generic Inheritance
“无参数”一词使我感到困惑。
实际上,即使没有指定通用参数的类型也具有参数。类型为 var arg = typeof( Base<> ).GetGenericArguments()[ 0 ];
Console.WriteLine( arg.DeclaringType ); // Base`1[T]
arg = typeof( Child<> ).BaseType.GetGenericArguments()[ 0 ];
Console.WriteLine( arg.DeclaringType ); // Child`1[T]
。
这些类型也可以被继承。与通常情况一样:
arg.IsGenericParameter == true
与无参数大小写相同:
typeof( Child<int> ).BaseType == typeof( Base<int> );
答案 2 :(得分:0)
您不仅需要也使用GetGenericTypeDefinition,而不仅仅是使用BaseType
:
var g = typeof(Base<>).IsGenericTypeDefinition;
var h = typeof(Child<>).BaseType.GetGenericTypeDefinition().IsGenericTypeDefinition;
var i = typeof(Base<>) == typeof(Child<>).BaseType.GetGenericTypeDefinition();
Reflection and Generic Types讨论了泛型上下文中涉及反射的一些复杂性。