加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 如何检查`IEnumerable`是否与`IEnumerable`协变?

发布时间:2020-12-15 08:19:00 所属栏目:百科 来源:网络整理
导读:什么是检查IEnumerable T1的常见规则.协调到IEnumerable T2 ? 我做了一些实验: 1. Object Obj = "Test string";IEnumerableObject Objs = new String[100]; 因为IEnumerable out T是协变的,String继承了Object. 2. interface MyInterface{}struct MyStruct
什么是检查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(…)函数是否正确?如果是,是否有任何更简单的方法来检查它?如果没有,如何解决?

另见这些文章:1,2.

解决方法

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

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读