IEnumerable<IEnumerable>> 和扩展方法

IEnumerable<IEnumerable>> and Extension Method

我想知道是否有人可以帮助我理解以下行为。在下面的代码中,我正在创建一个 CustomObject 实例,其中包含一个类型为 IEnumerable<IEnunumerable>>.

的单个 属性

我在 IEnumerable<T> 上还有一个名为 AsDataTable 的扩展方法。

public class CustomObject
{
public IEnumerable<IEnumerable> Collection {get;set;}
}


public static class ExtensionMethods
{

public static bool AsDataTable<T>(this IEnumerable<T> list)

{
    Console.Write("In extension method");
    return default(bool);
}
}

void Main()
{

    var ttObject = new CustomObject()
    {
        Collection = new List<IEnumerable>
        {
            new List<int>{1,2,3},
            new [] {new{A="abc",B="def"}}
        } 
    };
    var dummy = new []{new {a='r'}}.AsDataTable();

    foreach(var item in ttObject.Collection)
    {
        var temp = item.AsDataTable();
        Console.WriteLine($"Item is IEnumerable : {item is IEnumerable}");
    }
}

是什么让我想知道下面的代码行是否有效(或者编译)

var dummy = new []{new {a='r',b='3'}}.AsDataTable();

而当我遍历 CustomObject 的集合 属性 然后执行相同的操作时,它不允许我编译。

var temp = item.AsDataTable(); // this doesn't work

奇怪的是下面一行 returns true 再次确认 'item' 确实是 IEnumerable.

 Console.WriteLine($"Item is IEnumerable : {item is IEnumerable}");

我猜这是因为扩展方法是在通用版本 IEnumerable<T> 上编写的,但是它如何在匿名类型数组(在 CustomObject 之外)上工作。

IEnumerable<T> 实现了 IEnumerable,反之亦然。

通过一些运行时黑客攻击,SomeType[] 实际上确实实现了 IEnumerable<SomeType>。另一方面,IEnumerable 不会 - 重载解析是在编译时完成的,因此编译器不知道集合中的 IEnumerable 项实际上也实现了 IEnumerable<int>.

如果您需要使用 IEnumerable,您需要在扩展方法中使用它。