比较接口的GenericTypeDefinition
简单的代码,我期望List<int>
的GenericTypeDefinition包含一个通用接口ICollection<>
。然而,我无法从List<int>
中推导出可接受的类型,这使我可以正确地比较它们。比较接口的GenericTypeDefinition
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
。
编辑
固定的,乔恩斯基特给了我正确的洞察到发生了什么事。
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>
具体地,当T
是用于IList<T>
类型参数。
想象一下,你有这样的事情:
public class Foo<T1, T2> : IEnumerable<T1>, IComparable<T2>
泛型类型定义包含了所有的信息 - 它“知道”,它是专门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));
不是最安全的类型比较。 – 2015-03-03 10:06:03
如果你提供一些学习的例子,你会高兴地同意。 – Amit 2015-03-03 10:10:08
正如Jon刚刚指出的,名称字符串中的T标识符不一定与其他名称字符串中的T相同。 – 2015-03-03 10:18:59
谢谢你,你给了我我需要的见解。 – 2015-03-03 10:14:13