c# - C# 编译器可以在泛型类型上使用带有 foreach 的鸭子类型(duck typing)吗?

标签 c# generics duck-typing

已经确定编译器可以执行鸭子类型(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/

相关文章:

c# - 如何动态调用具有已知参数基类型的委托(delegate)?

当方法签名为 Map<String, IMyInterface> 且 MyClass 实现 IMyInterface 时,Java 将不接受 Map<String, MyClass> 参数

c# - 应该使用委托(delegate)的一些常见场景是什么?

c# - 无法直观地更改继承形式的 DataGridView

c# - C# 中的字节数组到字符串

interface - 我应该用 Duck Typed 语言定义接口(interface)吗?

ruby - 如何检测类似数组或类似集合的值,同时避免类型检查

c# - Linq 语句需要优化

java - 具有扩展 Comparable 的泛型类型参数的强制转换接口(interface)

ruby - 一般来说,避免 "undefined method ' some_method' for nil :NilClass"in Ruby