在C#中,为什么匿名方法不能包含yield语句?

2024-01-01

我认为做这样的事情会很好(使用 lambda 进行收益返回):

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();
}

但是,我发现我不能在匿名方法中使用yield。我想知道为什么。这产量文档 http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx只是说不允许。

由于不允许,我只是创建了列表并将项目添加到其中。


Eric Lippert 最近写了一系列关于为什么在某些情况下不允许使用屈服的博客文章。

  • Part 1 https://learn.microsoft.com/en-us/archive/blogs/ericlippert/
  • Part 2 https://learn.microsoft.com/en-us/archive/blogs/ericlippert/
  • Part 3 https://learn.microsoft.com/en-us/archive/blogs/ericlippert/
  • Part 4 https://learn.microsoft.com/en-us/archive/blogs/ericlippert/
  • Part 5 https://learn.microsoft.com/en-us/archive/blogs/ericlippert/
  • Part 6 https://learn.microsoft.com/en-us/archive/blogs/ericlippert/

EDIT2:

  • Part 7 https://learn.microsoft.com/en-us/archive/blogs/ericlippert/iterator-blocks-part-seven-why-no-anonymous-iterators (这个是后来发的,专门解决了这个问题)

您可能会在那里找到答案......


EDIT1:这在第 5 部分的评论中进行了解释,在 Eric 对 Abhijeet Patel 评论的回答中:

Q :

Eric,

您还可以提供一些见解吗 为什么“yield”不允许在 匿名方法或 lambda 表达式

A :

好问题。我很想拥有 匿名迭代器块。这将是 能够建造真是太棒了 自己一个小序列生成器 就地关闭本地 变量。不这样做的原因是 简单明了:好处不 超过成本。的厉害之处 使序列生成器就地是 实际上很小 事物的计划和名义方法 在大多数方面都做得足够好 场景。所以好处不是 如此引人注目。

成本是很大的。迭代器 重写是最复杂的 编译器中的转换,以及 匿名方法重写是 第二个最复杂的。匿名的 方法可以位于其他匿名方法内部 方法和匿名方法可以是 在迭代器块内。所以, 我们首先要做的是重写所有内容 匿名方法,使它们成为 闭包类的方法。这是 编译器的倒数第二件事 在为方法发出 IL 之前执行的操作。 一旦该步骤完成,迭代器 重写者可以假设没有 迭代器中的匿名方法 堵塞;它们都被重写了 已经。因此迭代器 重写者可以专注于 重写迭代器,无需 担心可能会有一个 那里未实现的匿名方法。

另外,迭代器块永远不会“嵌套”, 与匿名方法不同。迭代器 重写器可以假设所有迭代器 块是“顶级”。

如果允许匿名方法 包含迭代器块,然后两者 这些假设都被抛诸脑后了。 你可以有一个迭代器块 包含一个匿名方法 包含一个匿名方法 包含一个迭代器块 包含一个匿名方法,并且... 恶心。现在我们必须重写 可以处理嵌套迭代器的 pass 块和嵌套匿名方法位于 同时,合并我们两个最 复杂的算法归为一 更复杂的算法。它会 真的很难设计、实施, 并测试。我们足够聪明,可以做到 所以,我确定。我们有一个聪明的团队 这里。但我们不想承担 “很高兴拥有”的巨大负担 但不是必需的”功能。--Eric

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在C#中,为什么匿名方法不能包含yield语句? 的相关文章

随机推荐