为什么泛型类型定义实现的接口会丢失类型信息
本文关键字:类型 信息 接口 泛型类型定义 实现 为什么 | 更新日期: 2023-09-27 18:22:24
例如,如果您运行以下代码。。。
Type IListType = new List<string>().GetType()
.GetInterface("IList`1")
.GetGenericTypeDefinition();
当您观察IListType
变量时,您会发现整个Type
实例具有所有可用属性,如FullName
和其他属性。
但是当你运行下面的代码时会发生什么呢?
Type IListType2 = typeof(List<>).GetInterface("IList`1")
现在,从泛型类型定义中获得的IListType
与第一个代码示例不同:大多数Type
属性将返回null。
这方面的主要问题是,当它们是同一类型时,IListType == IListType2
并不相等。
怎么回事?
这太难看了
现在看看如果您调用IListType2.GetGenericTypeDefinition()
会发生什么。。。它恢复类型信息!
如果.NET Framework开发团队成员能够向我们解释为什么已经是泛型的类型定义(它奇怪地丢失了元数据)的IsGenericTypeDefinition
属性设置为false
,而它仍然是泛型类型定义,那么这将是一件很好的事,最后,如果您对它调用GetGenericTypeDefinition()
,则可以恢复类型信息。
这很奇怪
以下等式为true
:
Type IListType = new List<string>().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<string>!
Type IListType2 = typeof(List<>).GetInterface("IList`1").GetGenericTypeDefinition();
bool y = IListType == IListType2;
以下类型都不同,并且没有通过继承关系连接:
IList<T>
IList<int>
IList<string>
所有这些都有不同的Type
对象,因为您可以用它们做不同的事情。后两者是前者的专门化。第一个是泛型类型定义(可以通过GetGenericTypeDefinition
获得)。
解释还有另一部分。当你说class List<T> : IList<T>
时,IList<T>
部分是而不是等于typeof(IList<>)
,因为它已经专用于T
。这不再是泛型类型定义。它是一种具体的类型,如IList<int>
。它专门将其唯一的类型参数绑定到List<T>
专门用于的T
。
LINQPad:的实验
Type bound = new List<string>().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<T>
的第一个版本是IList<T>
的实际类型化版本,比如说IList<string>
。
第二个是CCD_ 27的一般定义,没有CCD_ 28的类型。
这使得两个接口不同。没有相同的,因为第一个是第二个的具体版本。