2009-02-04 69 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

這支持由安德魯·黑爾在此發佈的調查結果。