什么是检查IEnumerable< T1>的常见规则.协调到IEnumerable< T2> ?
我做了一些实验:
1.
Object Obj = "Test string"; IEnumerable<Object> Objs = new String[100];
因为IEnumerable< out T>是协变的,String继承了Object.
2.
interface MyInterface{} struct MyStruct:MyInterface{} ..... Object V = new MyStruct(); Console.WriteLine(new MyStruct() is Object); // Output: True. IEnumerable<Object> Vs = new MyStruct[100]; // Compilation error here
MyStruct实际上是一个Object,但它不起作用,因为Object是引用类型而MyStruct是值类型.好的,我在这看到一些逻辑.
3.
Console.WriteLine(new MyStruct() is ValueType); // Output: "True" ValueType V2 = new MyStruct(); IEnumerable<ValueType> Vs2 = new MyStruct[100]; // Compilation error here
应该工作,因为IEnumerable< out T>是协变和MyStruct是ValueType,但不起作用……好吧,也许MyStruct实际上并没有继承ValueType ….
4.
MyInterface V3 = new MyStruct(); Console.WriteLine(V3 is MyInterface); // Output: "True" IEnumerable<MyInterface> Vs3 = new MyStruct[100]; // Compilation error here
即使这样:“无法将MyStruct转换为MyInterface”.真的吗??你刚才做了一行……
我试图制定共同规则:
public static bool IsCovariantIEnumerable(Type T1,Type T2 ){ return (T2.IsAssignableFrom(T1)) && !T2.IsValueType; // Is this correct?? }
因此,问题是如何实际确定IEnumerable< T1>协变到IEnumerable< T2>?我的IsCovariantIEnumerable(…)函数是否正确?如果是,是否有任何更简单的方法来检查它?如果没有,如何解决?
解决方法
在您的特定情况下,它不起作用,因为值类型不支持协方差.
但是对于如何确定IEnumerable< T2>的问题.是IEnumerable< T1>的共变体:
方法Type.IsAssignableFrom()告诉您某个类型的实例是否已分配给此类型的变量.所以你可以这样实现你的方法:
public static bool IsCovariantIEnumerable(Type T1,Type T2) { Type enumerable1 = typeof(IEnumerable<>).MakeGenericType(T1); Type enumerable2 = typeof(IEnumerable<>).MakeGenericType(T2); return enumerable1.IsAssignableFrom(enumerable2); }
用法:
if (IsCovariantIEnumerable(typeof(object),typeof(string)) Console.WriteLine("IEnumerable<string> can be assigned to IEnumerable<object>");
但IsCovariantIEnumerable(typeof(object),typeof(MyStruct))将返回false,原因如上所述.
为了完整性:当然你不需要额外的方法,因为你可以很容易地做typeof(IEnumerable< object>).IsAssignableFrom(typeof(IEnumerable< string>).