为什么泛型类型定义实现的接口失去类型信息? [英] Why a generic type definition implemented interfaces lose type information?

查看:300
本文介绍了为什么泛型类型定义实现的接口失去类型信息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如,如果您运行下面的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆