C#编译器是否可以在普通类型上使用带有foreach的鸭子类型?

Ema*_*ren 4 c# generics duck-typing

已经确定,当迭代List或Array时,编译器可以执行鸭子类型处理以消除一些开销(请参阅C#编译器中的鸭子类型),因为这些类型将其IEnumerator实现为堆栈分配的结构。

即使类型是通用的,但受约束实现IEnumerable时也是如此吗?

为了提供更多的特异性,选项B的运行开销是否可以低于A?

A:

public static IEnumerable<T> Flatten<T>(this IEnumerable<IEnumerable<T>> collection)
{
    foreach (var subCollection in collection)
        foreach (var element in subCollection)
            yield return element;
}
Run Code Online (Sandbox Code Playgroud)

B:

public static IEnumerable<T> Flatten<TList, T>(this TList collection)
    where TList : IEnumerable<IEnumerable<T>>
{
    foreach (var subCollection in collection)
        foreach (var element in subCollection)
            yield return element;
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 6

不,基本上。“ B”的唯一用法是当其TList 本身实际上是a时struct;然后,IL可以使用“受约束的调用”来调用原始文件,GetEnumerator() 不必对原始struct TList值进行装箱。

但是:一旦调用GetEnumerator(),您就会回到IEnumerator<T>土地上,它将不会使用自定义迭代器。

在这种情况下,所有这些都无济于事,因为迭代器块相当“可分配”。因此...如果TList您不担心使用boxing ,那么您大概会对分配很着迷:在这种情况下,您也不会以这种方式编写iterator块。