【问题标题】:foreach vs ForEach using yieldforeach 与 ForEach 使用产量
【发布时间】:2016-06-24 02:48:17
【问题描述】:

是否可以在ForEach 方法中使用yield 内联?

private static IEnumerable<string> DoStuff(string Input)
{
    List<string> sResult = GetData(Input);
    sResult.ForEach(x => DoStuff(x));

    //does not work
    sResult.ForEach(item => yield return item;); 

    //does work
    foreach(string item in sResult) yield return item;
}

如果没有,是否有它不起作用的原因?

【问题讨论】:

  • 首先,为什么使用这种语法而不是.Select(x=&gt;DoStuff(x))?其次,ForEach 不返回结果,因此尝试使用returnyield 返回内容是无效的
  • @PanagiotisKanavos Select 不能与递归方法结合使用
  • @fubo 实际上,您可以找到使其工作的方法。您会发现许多示例展示了如何使用 LINQ 行走树木。至少您可以使用.Concat 组合递归结果,然后从选择返回结果。不过,尝试在 Action 中使用 yield 是完全无效的。
  • 看起来您想要做的是类似于foreach(var item in GetData(Input)) { foreach(var sub in DoStuff(item)){ yield return sub; } yield return item;} 或者您可能希望在sub 项目之前产生item

标签: c# yield


【解决方案1】:

不,List&lt;T&gt;.ForEach 不能用于此。

List&lt;T&gt;.ForEach 接受 Action&lt;T&gt; 委托。

Action&lt;T&gt; "封装了一个只有一个参数并且不返回值的方法。"

因此,如果要“适合”Action&lt;T&gt;,您创建的 lambda 将无法返回任何内容。

【讨论】:

    【解决方案2】:

    因为您可以看到here lambda 函数被编译为单独的方法:

    这个:

    x => DoStuff(x)
    

    转换为

    internal void <DoStuff>b__1_0(string x)
    {
        C.DoStuff(x);
    }
    

    这个单独的方法不是IEnumerable&lt;&gt;,所以它显然不支持yield关键字。

    例如:

    item => yield return item;
    

    将转换为:

    internal void <DoStuff>b__1_0(string item)
    {
        yield return item;
    }
    

    具有yield 但不是IEnumerable&lt;string&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-10
      • 1970-01-01
      • 2013-04-26
      • 2011-02-17
      • 2013-03-26
      • 2017-09-30
      • 1970-01-01
      相关资源
      最近更新 更多