下面的代码段打印出“类型不一样。”。为什么?我知道使用interfaceOnMyType.GetGenericTypeDefinition()
将解决问题,但为什么我必须这样做?
class Program
{
static void Main(string[] args)
{
var myType = typeof(Baz<>);
var interfaceOnMyType = myType.GetInterfaces().SingleOrDefault();
var exactType = typeof(IBar<>);
if (exactType == interfaceOnMyType)
{
Console.WriteLine("The types ARE the same.");
}
else
{
Console.WriteLine("The types ARE NOT the same.");
}
Console.ReadLine();
}
}
interface IBar<T>
{
}
class Baz<T> : IBar<T>
{
}
答案 0 :(得分:3)
interfaceOnMyType.GetGenericTypeDefinition()
返回接口的闭合构造类型,该类型与
返回的类型不同typeof(IBar<>)
Here is the MSDN article on GetGenericTypeDefinition
,这里有一个很好的引用,解释它是如何工作的:
给定表示此构造类型的
Type
对象,GetGenericTypeDefinition
方法返回泛型类型定义。
我想我现在可能已经找到了。类型比较失败的原因是因为Type
返回的myType.GetInterfaces()
接近但不等于接口本身的类型。
根据MSDN:
如果使用
BaseType
属性获取Derived
的基类型,则生成的Type对象的FullName
属性将返回null
(在Visual Basic中为Nothing)。要获取非空FullName
,可以使用GetGenericTypeDefinition
方法获取泛型类型定义。
所以我认为这是你所看到的问题。由于基本接口是通过GetInterfaces
检索的,因此该调用检索的任何类型都不会有FullName
(source)。由于它没有FullName
,因此类型将会失败。
如果你要比较你不是的构造类型,那么我所写的是真实的。所以不幸的是我的第一个答案是错误的 - 我已经离开了它,以便留下的评论是有意义的。
答案 1 :(得分:0)
原因是interfaceOnMyType.IsGenericTypeDefinition
返回false,而myType.IsGenericTypeDefinition
和exactType.IsGenericTypeDefinition
都返回true。也就是说,仅仅因为您从泛型类型定义中检索非构造泛型类型并不意味着您检索的类型本身就是泛型类型定义。
答案 2 :(得分:0)
尝试以下
Console.WriteLine("{0}", (null != exactType.FullName) ? exactType.FullName : "null");
Console.WriteLine("{0}", (null != interfaceOnMyType.FullName) ? interfaceOnMyType.FullName : "null");
输出结果为:
test.Program + IBar`1
null
这支持Andrew Hare在此发布的调查结果。