2015-03-03 10 views
6

Codice semplice che mi aspetto che la GenericTypeDefinition di List<int> contenga un'interfaccia generica di ICollection<>. Tuttavia non posso ricavare un tipo accettabile da List<int> che mi consente di confrontarli correttamente.Confronto tra GenericTypeDefinition of interfacfaces

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)); 
    } 
} 

uscita

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 

mi sarei aspettato che r1 conteneva un tipo che è stato pari a b.

EDIT

fisso, Jon Skeet mi ha dato l'intuizione giusta in quello che stava accadendo.

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)); 


    } 
} 

uscita

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 

risposta

7

No, la definizione di tipo generico riferirò a ICollection<T> specificamente, dove T è il parametro tipo per la IList<T>.

Immagina di avere qualcosa di simile:

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

La definizione di tipo generico contiene tutte le informazioni - è "sa" che è specificamente IEnumerable<T1> e IComparable<T2>, non IEnumerable<T2> e IComparable<T1> per esempio.

È possibile correggere l'assegno da ottenere la definizione di tipo generico per ciascuna delle interfacce implementate dal tipo:

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

Grazie, mi hai dato l'intuizione di cui avevo bisogno. –

0

Prova sotto la linea ..

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

Invece di

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

Non il più sicuro tra i tipi di confronto. –

+0

sarà felicemente d'accordo se fornisci qualche apprendimento con l'esempio. – Amit

+0

Come Jon ha appena sottolineato l'identificatore T nella stringa Name non è necessariamente la stessa T dell'altra stringa Name. –