比较接口的 GenericTypeDefinition

Comparing GenericTypeDefinition of interfaces

我希望 List<int> 的 GenericTypeDefinition 包含 ICollection<> 的通用接口的简单代码。但是我无法从 List<int> 派生出可接受的类型,这使我可以正确地比较它们。

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 的类型。

编辑

已修复,Jon Skeet 让我对正在发生的事情有了正确的认识。

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

不,泛型类型定义将具体引用 ICollection<T>,其中 TIList<T>.

的类型参数

想象一下你有这样的东西:

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

泛型类型定义包含所有这些信息 - "knows" 具体是 IEnumerable<T1>IComparable<T2>,而不是 IEnumerable<T2>IComparable<T1>

您可以通过获取类型实现的每个接口的通用类型定义来修复检查:

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

试试下面的行..

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

而不是

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