Mat*_*zer 9 .net c# generics reflection equality
例如,如果您运行以下代码...
Type IListType = new List<string>().GetType()
.GetInterface("IList`1")
.GetGenericTypeDefinition();
Run Code Online (Sandbox Code Playgroud)
...而且你看IListType
变量,你会发现整个Type
实例都有像FullName
其他的一样可用的属性.
但是当你运行代码时会发生什么?
Type IListType2 = typeof(List<>).GetInterface("IList`1")
Run Code Online (Sandbox Code Playgroud)
现在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;
Run Code Online (Sandbox Code Playgroud)
以下类型都是不同的,并且没有通过继承关系连接:
IList<T>
IList<int>
IList<string>
所有这些都有不同的Type
对象,因为你可以用它们做不同的事情.后两者是前者的专业.第一个是泛型类型定义(您可以通过它获得GetGenericTypeDefinition
).
解释还有另一部分.当你说class List<T> : IList<T>
那个IList<T>
部分不等于typeof(IList<>)
因为它已经专门化了T
.这不再是泛型类型定义.它是一种具体的类型IList<int>
.这是一家专业以它唯一的类型参数绑定到T
这List<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
Run Code Online (Sandbox Code Playgroud)