在C#中,为什么不能匿名方法包含yield语句? [英] In C#, why can't an anonymous method contain a yield statement?

查看:419
本文介绍了在C#中,为什么不能匿名方法包含yield语句?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为这将是很好做这样的事情(与拉姆达做产量返程):

I thought it would be nice to do something like this (with the lambda doing a yield return):

public IList<T> Find<T>(Expression<Func<T, bool>> expression) where T : class, new()
{
    IList<T> list = GetList<T>();
    var fun = expression.Compile();

    var items = () => {
        foreach (var item in list)
            if (fun.Invoke(item))
                yield return item; // This is not allowed by C#
    }

    return items.ToList();
}

不过,我发现我不能使用匿名方法的产量。我不知道为什么。该产量文档只说这是不允许的。

由于这是不允许我刚刚创建列表和添加的项目吧。

Since it wasn't allowed I just created List and added the items to it.

推荐答案

埃里克利珀最近写了一篇关于为什么产量不在某些情况下允许的系列博客文章。

Eric Lippert recently wrote a series of blog posts about why yield is not allowed in some cases.

  • Part 1
  • Part 2
  • Part 3
  • Part 4
  • Part 5
  • Part 6

EDIT2:


  • Part 7 (这个后来被公布,并专门解决这个问题)

  • Part 7 (this one was posted later and specifically addresses this question)

您可能会找到答案......

You will probably find the answer there...

EDIT1:这是在第5部分的注释说明,在Eric的回答Abhijeet帕特尔的评论:

this is explained in the comments of Part 5, in Eric's answer to Abhijeet Patel's comment:

问:

埃里克

您也可以提供一些见解
  为什么收益率是不允许的内
  匿名方法或lambda前pression

Can you also provide some insight into why "yields" are not allowed inside an anonymous method or lambda expression

答:

好问题。我很想有
  匿名迭代器块。这将是
  完全真棒要能够建立
  自己一点序列发生器
  在地方,关闭了当地的
  变量。之所以不就是
  直截了当:益处不大
  利大于弊。迷死
  使序列生成器在地方
  实际上pretty在盛大小
  事物和标称方法方案
  做的工作在大多数不够好
  场景。这样的好处是不
  那炫目。

Good question. I would love to have anonymous iterator blocks. It would be totally awesome to be able to build yourself a little sequence generator in-place that closed over local variables. The reason why not is straightforward: the benefits don't outweigh the costs. The awesomeness of making sequence generators in-place is actually pretty small in the grand scheme of things and nominal methods do the job well enough in most scenarios. So the benefits are not that compelling.

代价是巨大的。迭代器
  重写是最复杂的
  变换中的编译器,和
  匿名方法改写为
  第二个最复杂的。匿名
  方法可以在里面其他匿名
  方法和匿名方法可以
  内部迭代器块。因此,
  我们做的是首先我们重写所有
  匿名方法,使他们成为
  封闭类的方法。这是
  第二最后一件事编译器
  不发光IL的方法之前。
  一旦该步骤完成后,迭代器
  改写可以假设没有
  在迭代器匿名方法
  块;他们都被改写
  已经。因此,迭代器
  重写可以只专注于
  重写迭代器,无
  担心有可能是一个
  在那里未实现匿名方法。

The costs are large. Iterator rewriting is the most complicated transformation in the compiler, and anonymous method rewriting is the second most complicated. Anonymous methods can be inside other anonymous methods, and anonymous methods can be inside iterator blocks. Therefore, what we do is first we rewrite all anonymous methods so that they become methods of a closure class. This is the second-last thing the compiler does before emitting IL for a method. Once that step is done, the iterator rewriter can assume that there are no anonymous methods in the iterator block; they've all be rewritten already. Therefore the iterator rewriter can just concentrate on rewriting the iterator, without worrying that there might be an unrealized anonymous method in there.

此外,迭代器块从不鸟巢,
  不像匿名方法。迭代器
  重写可以假定所有的迭代器
  块是顶级。

Also, iterator blocks never "nest", unlike anonymous methods. The iterator rewriter can assume that all iterator blocks are "top level".

如果匿名方法允许
  包含迭代器块,那么这两个
  这些假设走出去的窗口。
  你可以有一个迭代器块
  包含一个匿名方法
  包含一个匿名方法
  包含一个迭代器块
  包含匿名方法,并...
  呸。现在我们来写一个重写
  通过能够处理嵌套的迭代器
  块和嵌套在匿名方法
  同时,将我们的两个最
  复杂的算法到一个远
  更复杂的算法。它会
  真的很难设计,实施,
  和测试。我们有足够的智慧做
  所以,我敢肯定。我们有一个聪明的团队
  这里。但是,我们不想承担
  一个漂亮的大型负担有
  但没有必要的功能 - 埃里克

If anonymous methods are allowed to contain iterator blocks, then both those assumptions go out the window. You can have an iterator block that contains an anonymous method that contains an anonymous method that contains an iterator block that contains an anonymous method, and... yuck. Now we have to write a rewriting pass that can handle nested iterator blocks and nested anonymous methods at the same time, merging our two most complicated algorithms into one far more complicated algorithm. It would be really hard to design, implement, and test. We are smart enough to do so, I'm sure. We've got a smart team here. But we don't want to take on that large burden for a "nice to have but not necessary" feature. -- Eric

这篇关于在C#中,为什么不能匿名方法包含yield语句?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆