C# 收益回报多少?

C# 收益回报多少?,c#,C#,我发现自己对IEnumerables进行了很多讨论,以便返回每个结果。有没有办法压缩这样的东西 foreach (var subSelector in subSelectors) { foreach (var node in FindSingle(context, subSelector)) yield return node; } 要删除内部foreach?否,没有,除非使用LINQ将每个yield return语句完全替换为单个return语句 例如: retur

我发现自己对IEnumerables进行了很多讨论,以便返回每个结果。有没有办法压缩这样的东西

foreach (var subSelector in subSelectors)
{
    foreach (var node in FindSingle(context, subSelector))
        yield return node;
} 

要删除内部foreach?

否,没有,除非使用LINQ将每个
yield return
语句完全替换为单个
return
语句

例如:

return someSet
    .Concat(someOtherSet.SelectMany(s => FindSingle(context, s));
使用:


只有当您的方法中没有任何其他收益率返回语句时,这才有效。

这是一个C#不支持的频繁请求的功能。有关详细信息,请参阅此连接项:

建议的语法通常类似于:

public static IEnumerable<T> PreorderTraversal<T>(this BinaryTree<T> root)
{
    if (root == null) yield break;
    yield return root.Item;
    yield foreach root.Left.PreorderTraversal();
    yield foreach root.Right.PreorderTraversal();
}
公共静态IEnumerable预订单Traversal(此二进制树根)
{
如果(root==null)产生中断;
产生返回根.Item;
每个根的产量。左。前序旅行();
每个根的产量。右。PreorderTraversal();
}
如果您对使用支持此功能的类C语言感兴趣,请查看Cω:

您可能还想阅读这篇关于Cω实现者的特性的文章:

如果您对支持此功能的非C语言感兴趣,请查看F的“yield!”功能。(我只是喜欢这个功能的名字是“屈服!”)

即使你对理论上的东西不感兴趣,听起来你也会把这种情况当作一个实际问题来面对。您还应该阅读Wes Dyer关于在不使用“yield foreach”的情况下高效执行这种嵌套迭代的技术的文章:


您可以将方法分成两部分。鉴于这些扩展方法:

public static class MultiEnumerableExtensions {
  public static IEnumerable<T> Pack<T>(this T item) {
    yield return item;
  }
  public static IEnumerable<T> Flatten<T>(
    this IEnumerable<IEnumerable<T>> multiList) {
    return multiList.SelectMany(x => x);
  }
}
公共静态类多枚举扩展{
公共静态IEnumerable包(此T项){
收益回报项目;
}
公共静态可数平坦(
此IEnumerable(可数多重列表){
返回multiList.SelectMany(x=>x);
}
}
使用Eric Lippert的,它变成了:

public static class BinaryTreeExtensions {
  public static IEnumerable<T> PreorderTraversal<T>(this BinaryTree<T> root) {
    return PreorderTraversalMulti(root).Flatten();
  }
  private static IEnumerable<IEnumerable<T>> PreorderTraversalMulti<T>(
    this BinaryTree<T> root) {
    if (root == null) yield break;
    yield return root.Item.Pack(); // this packs an item into an enumerable
    yield return root.Left.PreorderTraversal();
    yield return root.Right.PreorderTraversal();
  }
}
公共静态类BinaryTreeExtensions{
公共静态IEnumerable PreorderTraversal(此二叉树根){
返回PreorderTraversalMulti(root).flatte();
}
私有静态IEnumerable预订单TraversalMulti(
此二叉树(根){
如果(root==null)产生中断;
yield return root.Item.Pack();//这会将项打包到可枚举项中
产生返回根.Left.PreorderTraversal();
产生返回根.Right.PreorderTraversal();
}
}
内部方法生成T的可枚举数而不是Ts,外部方法只需将此结果展平。

使用Linq的威力

return subSelectors.SelectMany(s => FindSingle(context, s));
在C#7.0中,允许使用本地函数,这使我们有了一个相当简洁的方法

IEnumerable<T> FlatEnumerable(){
    IEnumerable<IEnumerable<T>> NestedEnumerable(){
       yield return myEnumerable1;
       yield return myEnumerable2;
    }

    return NestedEnumerable().SelectMany(e => e);
}
IEnumerable FlatEnumerable(){
IEnumerable nestednumerable(){
收益率1;
收益率2;
}
返回nestednumerable().SelectMany(e=>e);
}

这已经被问了很多次,应该合并。搜索“yield multiple enumerable”@mafurtct:未找到“yield multiple enumerable”的结果。你能举个例子吗?这是我发现的(当然,用不同的搜索短语):。然而,我并没有发现我正在寻找的问题能够准确地解释我的要求。我还记得不久前我自己问过这个问题。。。我会试着在我的Q列表中查找它。它可能是,这与这个问题并不相关。(我感觉自己就像一个维基百科(甚至是一个德国维基百科)。对此感到抱歉)是的。。。琼:C-omega的一些想法已经被整合到C#中,有些还没有。我不知道是否有任何研究或开发继续进行,我认为只要
每一个
都能产出,听起来会更好。谢谢你的回答!这很有趣。或者说“Yieldmanny”,这与SelectMany@mpen您当前可以使用
yield
作为类名,使用
each
作为变量名,因此可能已经有代码包含单词
yield each
。现在c#可以确定
收益率
中的
收益率
是一个关键字,因为它后面跟着另一个关键字;因此,同样地,
yield-foreach
可能更好。@StrategyThinker:的确,这是标准的语法;请参阅Kiril 2007年的文章:对于少量的语法糖来说,似乎有很多开销。不过,我很欣赏这个建议,它很有趣。使用它可能有一个门槛。如果您的方法中有多个“foreach收益率”,则可能会出现这种情况。我认为埃里克的例子几乎不符合条件。其他人可能会有不同的想法。我想知道投票失败的原因。。这是短的和可维护的。我认为这真的很干净。好建议!我将它与一个扁平的扩展相结合,以便更清晰地阅读。公共静态IEnumerable展平(此IEnumerable源)=>source.SelectMany(x=>x);hm-有人可以添加一个关于如何使用它的示例吗?我不完全了解这里发生了什么。在这种情况下,本地函数完全没有必要,因为你可以简单地创建这些可枚举的数组。尽管如此,它并不完全相同,因为“return”会立即从函数中退出,而“yield return”则不会
IEnumerable<T> FlatEnumerable(){
    IEnumerable<IEnumerable<T>> NestedEnumerable(){
       yield return myEnumerable1;
       yield return myEnumerable2;
    }

    return NestedEnumerable().SelectMany(e => e);
}