如何检查`IEnumerable <t1>`covariant到`IEnumerable <t2>`?

时间:2016-08-30 10:57:17

标签: c# ienumerable covariance

检查where date + hour * interval '1 hour' >= xxxx + hhhh * interval '1 hour' and date + hour * interval '1 hour' < yyyy + hhhh * interval '1 hour' 是否IEnumerable<T1>协变的常见规则是什么?

我做了一些实验:

1

IEnumerable<T2>

有效,因为Object Obj = "Test string"; IEnumerable<Object> Objs = new String[100]; 是协变的,而IEnumerable<out T>是继承String

2

Object

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是值类型。好的,我在这里看到一些逻辑。

第3

MyStruct

应该有效,因为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 1}} ...

4

ValueType

即便如此:&#34;无法将MyStruct转换为MyInterface&#34;。真的吗??你刚才做了一行...

我试图制定共同规则:

MyInterface V3 = new MyStruct(); 
Console.WriteLine(V3 is MyInterface); // Output: "True" 
IEnumerable<MyInterface> Vs3 = new MyStruct[100]; // Compilation error here

那么,问题是如何实际确定public static bool IsCovariantIEnumerable(Type T1, Type T2 ){ return (T2.IsAssignableFrom(T1)) && !T2.IsValueType; // Is this correct?? } 是否与IEnumerable<T1>协变?我的IEnumerable<T2>功能是否正确?如果是,是否有任何更简单的方法来检查它?如果没有,如何解决?

另请参阅以下文章:12

2 个答案:

答案 0 :(得分:5)

在您的特定情况下,它不起作用,因为值类型不支持协方差。

但是对于如何确定如果 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>)

答案 1 :(得分:2)

值类型不支持协方差,因为它会更改其内部表示[1]

如果你想避免奇怪的情况,我建议改为使用IsAssignableFrom

public static bool IsCovariantIEnumerable(Type T1, Type T2) => T1.IsAssignableFrom(T2);