微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

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()在它上面,你恢复了类型信息.

这很奇怪…

以下等式将成立:

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获取).

解释还有另一部分.当你说课程列表< T> :IList< T>那么IList< T> part不等于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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐