2015-03-03 21 views
6

Mã đơn giản mà tôi mong đợi List<int> 'GenericTypeDefinition để chứa giao diện chung của ICollection<>. Tuy nhiên, tôi không thể lấy được một loại có thể chấp nhận được từ List<int> cho phép tôi so sánh chúng một cách chính xác.So sánh GenericTypeDefinition của giao diện

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 

tôi lại có thể ngờ rằng r1 chứa một loại đó là bằng b.

EDIT

cố định, Jon Skeet đã cho tôi cái nhìn sâu sắc ngay vào những gì đang xảy ra.

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 

Trả lời

7

Không, định nghĩa kiểu generic sẽ đề cập đến ICollection<T> đặc biệt, nơi T là tham số kiểu cho các IList<T>.

Hãy tưởng tượng bạn có một cái gì đó như:

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

Định nghĩa kiểu generic chứa tất cả các thông tin đó - nó "biết" rằng đó là đặc biệt IEnumerable<T1>IComparable<T2>, không IEnumerable<T2>IComparable<T1> ví dụ.

Bạn có thể sửa chữa kiểm tra bằng cách định nghĩa kiểu chung cho mỗi người trong số các giao diện được thực hiện bởi các loại:

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

Cảm ơn bạn, bạn đã cho tôi cái nhìn sâu sắc mà tôi cần. –

0

Hãy thử bên dưới dòng ..

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

Thay vì

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

Không phải là loại so sánh an toàn nhất. –

+0

Sẽ vui vẻ đồng ý nếu bạn cung cấp một số việc học bằng ví dụ. – Amit

+0

Vì Jon vừa chỉ ra mã định danh T trong chuỗi Tên không nhất thiết phải giống T như trong chuỗi Tên khác. –

Các vấn đề liên quan