为什么泛型类型定义实现的接口失去类型信息? [英] Why a generic type definition implemented interfaces lose type information?
问题描述
例如,如果您运行下面的code ...
键入IListType =新的名单,其中,串>的GetType()()
.GetInterface(IList`1)
.GetGenericTypeDefinition();
...你看 IListType
变量中,你会发现整个键入
实例具有所有属性可像全名
等。
但是,当您运行code波纹管会发生什么情况?
键入IListType2 =的typeof(名单<>)。GetInterface(IList`1)
现在 IListType
从泛型类型定义得到的是不一样的第一code样品:大多数键入
属性将返回null。
这样做的主要问题是, IListType == IListType2
不相等,它们是相同的类型。
这是怎么回事?
这是丑陋的...
现在看,如果你调用 IListType2.GetGenericTypeDefinition()
...它恢复类型的信息会发生什么!
这将是巨大的,一个.NET Framework开发团队成员能够解释我们为什么一个的已经泛型类型定义已经很奇怪失去了它的元数据的有 IsGenericTypeDefinition
属性设置为假
同时它还是一个泛型类型定义,最后,如果你调用 GetGenericTypeDefinition()
上它,你恢复的数据类型的信息。
这就奇怪了......
下面的平等是真
:
键入IListType =新的名单,其中,串>的GetType()()
.GetInterface(IList`1)
.GetGenericTypeDefinition();
// GOT的接口是像一个泛型类型定义,因为它有
//没有类型对于T泛型参数,一旦你打电话
// GetGenericTypeDefinition()再次,它恢复丢失的元数据
//所得泛型类型定义等于从一个有
//名单,其中,字符串>!
键入IListType2 =的typeof(名单<>)GetInterface(IList`1)GetGenericTypeDefinition()。
布尔Y = IListType == IListType2;
以下类型都是不同的,而不是通过继承关系:
-
的IList< T>
-
的IList< INT>
-
的IList<字符串>
所有这些都有不同的键入
的对象,因为你可以做不同的事情他们。后两者是前者的专业。首先是泛型类型定义(您可以通过获得 GetGenericTypeDefinition
)。
还有另一部分的说明。当你说类List< T> :IList的< T>
则的IList< T>
部分的没有的等于的typeof (IList的<>)
因为它已经专门为 T
。这已经不再是一个泛型类型定义。这是一个具体的类型,如的IList< INT>
。它是专门为它唯一的类型参数的 T
的名单,其中结合; T>
是一家专业为
实验LINQPad:
类型约束=新的名单,其中,串>()的GetType()GetInterface(IList`1);
bound.GenericTypeArguments.Single()转储()。 //串
键入势必=的typeof(名单<>)。GetInterface(IList`1);
bound.GenericTypeArguments.Single()转储()。 //T
(bound.GenericTypeArguments.Single()== typeof运算(名单<>。)GetGenericArguments()单()。)转储()。 //真正
For example, if you run the following code...
Type IListType = new List<string>().GetType()
.GetInterface("IList`1")
.GetGenericTypeDefinition();
...and you watch IListType
variable, you'll find that the whole Type
instance has all properties available like FullName
and others.
But what happens when you run the code bellow?
Type IListType2 = typeof(List<>).GetInterface("IList`1")
Now IListType
got from a generic type definition isn't the same as the first code sample: most Type
properties will return null.
The main issue with this is that IListType == IListType2
doesn't equal while they're the same type.
What's going on?
This is ugly...
Now see what happens if you call IListType2.GetGenericTypeDefinition()
... It recovers the type information!
It would be great that a .NET Framework development team member could explain us why an already generic type definition which has strangely lost its metadata has IsGenericTypeDefinition
property set to false
while it's still a generic type definition, and finally, if you call GetGenericTypeDefinition()
on it, you recover the type information.
This is strange...
The following equality will be 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;
The following types are all different and not connected by an inheritance relationship:
IList<T>
IList<int>
IList<string>
All of these have different Type
objects because you can do different things with them. The latter two are the specializations of the former. The first is the generic type definition (which you can obtain through GetGenericTypeDefinition
).
There is another part to the explanation. When you say class List<T> : IList<T>
then the IList<T>
part is not equal to typeof(IList<>)
because it is already specialized to T
. This is no longer a generic type definition. It is a concrete type such as IList<int>
. It is specialized to bind its only type argument to the T
that List<T>
was specialized to.
Experiment for 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
这篇关于为什么泛型类型定义实现的接口失去类型信息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!