2009-02-04 72 views
3

下面的代码段输出“类型不一样”。为什么?我知道使用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

原因是interfaceOnMyType.IsGenericTypeDefinition返回false,而myType.IsGenericTypeDefinitionexactType.IsGenericTypeDefinition都返回true。也就是说,仅仅因为您从泛型类型定义中检索非构造泛型并不意味着您检索的类型本身就是泛型定义。

3
interfaceOnMyType.GetGenericTypeDefinition() 

回报你的封闭构造类型的接口是从

typeof(IBar<>) 

Here is the MSDN article on GetGenericTypeDefinition返回的类型不同,这里是一个很好的报价,从它解释它是如何工作的:

鉴于代表此构造类型的Type对象,GetGenericTypeDefinition方法返回泛型类型定义。


编辑(以上答案是在某些情况下,正确的,但错在这一个):

我想我现在可能已经找到了。类型比较失败的原因是因为从myType.GetInterfaces()返回的Type与接口本身的类型接近但不相同。

根据MSDN

如果使用BaseType属性来获得Derived的基本类型,结果类型对象的FullName属性返回null(在Visual Basic中为Nothing)。要获得非空值FullName,可以使用GetGenericTypeDefinition方法来获取泛型类型定义。

所以我认为这是你所看到的问题。由于基础接口通过GetInterfaces检索,通过该调用检索到的任何类型都不会有FullNamesource)。由于它没有FullName,所以类型将会失败。

如果你正在比较你所没有的构造类型,我最初写的东西是真的。所以不幸的是,我的第一个答案是错误的 - 我已经离开了,所以留下的意见会有意义。

+0

不,他们是一样的 - 试试吧。 – 2009-02-04 14:45:12

0

请尝试以下

  Console.WriteLine("{0}", (null != exactType.FullName) ? exactType.FullName : "null"); 
      Console.WriteLine("{0}", (null != interfaceOnMyType.FullName) ? interfaceOnMyType.FullName : "null"); 

输出是:

test.Program + IBar`1

这支持由安德鲁·黑尔在此发布的调查结果。