2015-03-03 57 views
6

簡單的代碼,我期望List<int>的GenericTypeDefinition包含一個通用接口ICollection<>。然而,我無法從List<int>中推導出可接受的類型,這使我可以正確地比較它們。比較接口的GenericTypeDefinition

using System; 
using System.Collections.Generic; 
using System.Linq; 

public class Test 
{ 
    public static void Main() 
    { 
     var a = typeof(List<int>); 
     var b = typeof(ICollection<>); 

     var r1 = a.GetGenericTypeDefinition().GetInterfaces(); 
     foreach (var x in r1) 
     { 
      Console.WriteLine(x); 
     } 
     Console.WriteLine(); 
     Console.WriteLine(b); 
     Console.WriteLine(); 
     Console.WriteLine(r1.Any(x => x == b)); 
    } 
} 

輸出

System.Collections.Generic.IEnumerable`1[T] 
System.Collections.Generic.IReadOnlyList`1[T] 
System.Collections.Generic.IReadOnlyCollection`1[T] 
System.Collections.IEnumerable 
System.Collections.Generic.IList`1[T] 
System.Collections.Generic.ICollection`1[T] 
System.Collections.ICollection 
System.Collections.IList 

System.Collections.Generic.ICollection`1[T] 

False 

我本來預計r1包含一種類型,是等於b

編輯

固定的,喬恩斯基特給了我正確的洞察到發生了什麼事。

using System; 
using System.Collections.Generic; 
using System.Linq; 

public class Test 
{ 
    public static void Main() 
    { 
     var a = typeof(List<int>); 
     var b = typeof(ICollection<>); 

     var r1 = a.GetInterfaces() 
      .Where(x => x.IsGenericType) 
      .Select(x => x.GetGenericTypeDefinition()); 

     foreach (var x in r1) 
     { 
      Console.WriteLine(x); 
     } 

     Console.WriteLine(); 
     Console.WriteLine(b); 
     Console.WriteLine(); 
     Console.WriteLine(r1.Contains(b)); 


    } 
} 

輸出

System.Collections.Generic.IEnumerable`1[T] 
System.Collections.Generic.IReadOnlyList`1[T] 
System.Collections.Generic.IReadOnlyCollection`1[T] 
System.Collections.Generic.ICollection`1[T] 
System.Collections.Generic.IList`1[T] 

System.Collections.Generic.ICollection`1[T] 

True 

回答

7

否,則通用類型定義將指ICollection<T>具體地,當T是用於IList<T>類型參數。

想象一下,你有這樣的事情:

public class Foo<T1, T2> : IEnumerable<T1>, IComparable<T2> 

泛型類型定義包含了所有的信息 - 它「知道」,它是專門IEnumerable<T1>IComparable<T2>,不IEnumerable<T2>IComparable<T1>例如。

您可以通過獲取泛型類型定義爲每個由類型實現的接口修復檢查:

Console.WriteLine(r1.Any(x => x.IsGenericType && 
           x.GetGenericTypeDefinition() == b)); 
+0

謝謝你,你給了我我需要的見解。 – 2015-03-03 10:14:13

0

試試下面一行..

Console.WriteLine(r1.Any(x => x.Name == b.Name)); 

而不是

Console.WriteLine(r1.Any(x => x == b)); 
+0

不是最安全的類型比較。 – 2015-03-03 10:06:03

+0

如果你提供一些學習的例子,你會高興地同意。 – Amit 2015-03-03 10:10:08

+0

正如Jon剛剛指出的,名稱字符串中的T標識符不一定與其他名稱字符串中的T相同。 – 2015-03-03 10:18:59