为什么通用类型定义实现的接口会丢失类型信息?

例如,如果您运行以下代码…

Type IListType = new List().GetType() .GetInterface("IList`1") .GetGenericTypeDefinition(); 

…并且您观察IListType变量,您会发现整个Type实例具有FullName等所有可用属性。

但是当你运行代码时会发生什么?

 Type IListType2 = typeof(List).GetInterface("IList`1") 

现在,来自generics类型定义的IListType与第一个代码示例不同:大多数Type属性将返回null。

这个问题的主要问题是IListType == IListType2不等于它们是相同的类型。

这是怎么回事?

这太丑了……

现在看看如果调用IListType2.GetGenericTypeDefinition()会发生什么……它恢复了类型信息!

.NET Framework开发团队成员可以解释为什么一个奇怪地丢失其元数据已经generics的类型定义为什么IsGenericTypeDefinition属性设置为false而它仍然是generics类型定义,最后,如果你调用GetGenericTypeDefinition()在它上面,你恢复了类型信息。

这很奇怪…

以下等式将true

 Type IListType = new List().GetType() .GetInterface("IList`1") .GetGenericTypeDefinition(); // Got interface is "like a generic type definition" since it has // no type for T generic parameter, and once you call // GetGenericTypeDefinition() again, it recovers the lost metadata // and the resulting generic type definition equals the one got from // List! Type IListType2 = typeof(List).GetInterface("IList`1").GetGenericTypeDefinition(); bool y = IListType == IListType2; 

以下类型都是不同的,并且没有通过inheritance关系连接:

  • IList
  • IList
  • IList

所有这些都有不同的Type对象,因为你可以用它们做不同的事情。 后两者是前者的专业。 第一个是generics​​类型定义(可以通过GetGenericTypeDefinition获取)。

解释还有另一部分。 当你说class List : IListIList部分等于typeof(IList<>)因为它已经专门用于T 这不再是generics类型定义。 它是一种具体的类型,如IList 。 它专门用于将其唯一的类型参数绑定到List专用的List


LINQPad实验:

 Type bound = new List().GetType().GetInterface("IList`1"); bound.GenericTypeArguments.Single().Dump(); //string Type bound = typeof(List<>).GetInterface("IList`1"); bound.GenericTypeArguments.Single().Dump(); //"T" (bound.GenericTypeArguments.Single() == typeof(List<>).GetGenericArguments().Single()).Dump(); //true 

IList的第一个版本是IList的实际类型版本,比如说IList

第二个是IList的通用定义,没有IList的类型。

这使得两个接口不同。 有不一样的,因为第一个是第二个的具体版本。