已经确定编译器可以执行鸭子类型(duck typing)以在遍历列表或数组时消除一些开销(请参阅 Duck typing in the C# compiler ),因为这些类型将其 IEnumerator 实现为堆栈分配结构。
即使类型是通用的,但受限于实现 IEnumerable 时也是这种情况吗?
为了给出更多的细节,选项 B 的运行开销是否可以低于 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;
}
乙:
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;
}
最佳答案
不,基本上。 “B”的唯一用途是当 TList
本身实际上是一个struct
;然后 IL 可以使用“约束调用”来调用原始的 GetEnumerator()
没有任何部分都必须装箱原件 struct TList
值(value)。
但是:一旦您调用了 GetEnumerator()
,你回到了IEnumerator<T>
着陆,它将不使用自定义迭代器。
在这种情况下,所有这些基本上都没有实际意义,因为迭代器 block 也相当“分配”。所以...如果避免装箱 TList
是您的顾虑,您可能对分配很着迷:在这种情况下,您也不会以这种方式编写迭代器 block 。
关于c# - C# 编译器可以在泛型类型上使用带有 foreach 的鸭子类型(duck typing)吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55027480/