为什么typeof(Child <>)。BaseType.IsGenericTypeDefinition为false?

时间:2018-08-05 12:38:55

标签: c# .net generics

示例:

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<> ) )不起作用。

3 个答案:

答案 0 :(得分:2)

我已经阅读了文档here,并解释了IsGenericTypeIsGenericTypeDefinition之间的区别。

您的BaseType属于此类:开放构造类型

  

ContainsGenericParameters属性为 true

     

示例是具有未分配的类型参数 a的泛型类型   嵌套在通用类型定义 中的类型   构造类型,或具有类型参数的泛型类型   ContainsGenericParameters属性为true。

     

无法创建开放构造类型的实例

因此,为了使类型定义通用,您必须能够从中创建一个实例。但是在这种情况下,BaseType是一个开放的构造类型,并且绑定到它的继承者:Child<T>,如果创建一个Child<int>,则基数变为Base<int>,而不是反之亦然。

因此,您不能直接通过调用BaseTypeMakeGenericType创建泛型类型实例,因为它的类型参数是在继承者类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讨论了泛型上下文中涉及反射的一些复杂性。