比较接口的GenericTypeDefinition

Gar*_*oyd 6 c# generics types

简单的代码,我希望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));
    }
}
Run Code Online (Sandbox Code Playgroud)

产量

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
Run Code Online (Sandbox Code Playgroud)

我原以为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));


    }
}
Run Code Online (Sandbox Code Playgroud)

产量

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
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 7

不,泛型类型定义将ICollection<T>具体指代,其中T是类型参数IList<T>.

想象一下你有类似的东西:

public class Foo<T1, T2> : IEnumerable<T1>, IComparable<T2>
Run Code Online (Sandbox Code Playgroud)

泛型类型定义包含了所有的信息-它"知道",它是专门IEnumerable<T1>IComparable<T2>,不IEnumerable<T2>IComparable<T1>的例子.

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

Console.WriteLine(r1.Any(x => x.IsGenericType && 
                              x.GetGenericTypeDefinition()  == b));
Run Code Online (Sandbox Code Playgroud)