Comparison of GenericTypeDefinition Interfaces

Simple code that I expect List<int> GenericTypeDefinition to contain the general interface ICollection<> . However, I cannot get an acceptable type from the List<int> , which allows me to compare them correctly.

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

Output

 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 

I would suggest that r1 contains a type equal to b .

EDIT

Fixed, John Skeet gave me the correct idea of ​​what was happening.

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

Output

 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 
+6
source share
2 answers

No, a generic type definition will refer to ICollection<T> in particular, where T is the type parameter for IList<T> .

Imagine you had something like:

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

The general type definition contains all this information - it "knows" that it is specifically IEnumerable<T1> and IComparable<T2> , and not IEnumerable<T2> and IComparable<T1> for example.

You can fix the check by obtaining a definition of a common type for each of the interfaces implemented by type:

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

Try the line below.

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

Instead

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

Source: https://habr.com/ru/post/983259/


All Articles