gpt4 book ai didi

c# - F# 屈服! operator - 实现和可能的 C# 等价物

转载 作者:可可西里 更新时间:2023-11-01 07:45:59 26 4
gpt4 key购买 nike

我目前正在学习 F#,我非常喜欢 yield! (yield-bang) 运算符。不仅因为它的名字,当然也因为它的作用。

yield! 运算符基本上允许您从序列表达式中产生序列的所有元素。这对于组合枚举器很有用。因为我经常遇到大而复杂的枚举器,所以我对我们可以用来将它们分解并由更简单的枚举器组合起来的策略很感兴趣。

不幸的是,yield! 运算符在 C# 中不可用。据我所知,它的作用类似于 foreach (var x in source) yield x; 但我正在阅读的书 ( Petricek's Real World F# - Manning ) 表明它具有更好的性能......

  • 那么 F# 编译器在这里究竟做了什么? (是的,我也可以使用 Reflector 查看它,但我想更详细地描述该机制)。

为了在 C# 中实现类似的构造,我探索了多种方法,但没有一种方法像 yield! 运算符那样简洁,而且我也不确定它们的复杂性。如果我的 BigO 数字正确,有人可以提供输入吗?

  • 将枚举器分解为多个私有(private)枚举器,然后从公共(public)枚举器中生成每个元素:

    foreach (var x in part1()) yield x
    foreach (var x in part2()) yield x

    这将有效地导致每个元素的“双倍产量”。那是O(2n)吗? (或者可能更糟?)无论如何,使用这种方法可以阻止我从我的任何子部分使用 yield break;

  • 将枚举器分解为多个私有(private)枚举器,然后将公共(public)枚举器中的所有私有(private)枚举器连接起来:

    return part1().Concat(part2())

    我相信这与上述解决方案没有什么不同,因为 Concat() 是按照我上面概述的方式实现的。

还有其他选择吗?

最佳答案

在当前的 C# 版本中,我认为除了 foreach... yield returnConcat 之外,您没有其他选择。我同意在 C# 中使用 yield! 运算符会很好,它会使某些构造更加优雅,但我怀疑此功能是否会进入“必备”列表,因为没有它我们也能轻松做到。

您可能对此感兴趣 MS research paper ,它引入了一个新的 yield foreach 结构:

IEnumerable<XmlNode> Traverse(XmlNode n)
{
yield return n;
foreach (XmlNode c in n.ChildNodes)
yield foreach Traverse(c);
}

关于您关于复杂性的问题:在这两种情况下都是 O(n)。未使用 O(2n),因为它表示与 O(n)(线性)相同的复杂性。我不认为你可以用当前的 C# 功能做得更好......

关于c# - F# 屈服! operator - 实现和可能的 C# 等价物,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3500488/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com