关于C#:yield break用途是什么?

What's the use of yield break?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
What does"yield break;" do in C#?

任何人都能看到使用"break"或"return"无法实现的"yield break"语句的用法吗?

这句话似乎毫无用处。此外,如果没有这个语句,"yield return x"语句可以简化为"yield x",这更易于阅读。

我错过了什么?


为了给出一个代码示例,假设您想编写一个迭代器,如果源为空或为空,则该迭代器不返回任何内容。

1
2
3
4
5
6
7
8
public IEnumerable<T> EnumerateThroughNull<T>(IEnumerable<T> source)
{
    if (source == null)
        yield break;

    foreach (T item in source)
        yield return item;
}

如果没有yield break,就不可能在迭代器中返回空集。


yield break指定该方法应停止返回结果。""返回"本身就不够好,甚至可能导致错误,因为方法的返回类型必须是IEnumerable。

我不知道为什么还需要返回关键字。我的最佳猜测是,这有助于使声明的意图更加清楚。

如果您感兴趣,本文将解释yield在幕后的作用。

在c yield关键字的幕后


屈服,休息,做完全不同的事情!看

1
2
3
4
5
6
7
8
9
10
11
12
13
for(int i = 0; i < 10; ++i) {
   if(i > 5) { break; }
   yield return i;
}

for(int v = 2710; v < 2714; v+=2) {
   yield return v;
}

for(int s = 16; s < 147; ++s) {
   if(s == 27) { yield break; }
   else if(s > 17) { yield return s; }
}

输出将是这些值中的一个整数:0、1、2、3、4、5、2710、2712、18、19、20、21、22、23、24、25、26

这里有一些方法没有任何用处,但它说明您可以将yield break和break组合成相同的方法,它们可以做两个不同的事情!断开只是跳出了循环,屈服断开完全结束了方法。

我猜没有使用返回的原因是因为您没有在方法中返回IEnumerable。此外,对于这种迭代的情况,你不认为收益率突破比回报更清楚吗?我亲自去做。


在迭代器块中使用return语句是非法的。此外,如果允许break语句影响迭代,那么它可以在迭代器块内起到双重作用:它可以用于中断循环或从开关中断,也可以用于中断整个迭代。

yield returnyield break,它们本身是两个关键字,似乎都是必要的。


return语句用于从函数返回值。

如果您有这样的迭代器函数:

1
public IEnumerable<int> IteratorOverInt() { }

上面函数中的RETURN语句需要返回一个已填充的IEnumerable

1
2
3
public IEnumerable<int> IteratorOverInt() {
    return new List<int> { 1, 2, 3, 4 };
}

但是,如果您正在使用迭代器函数,那么您将使用yield return,因此您的代码可能如下所示:

1
2
3
4
5
public IEnumerable<int> IteratorOverInt() {
    for (int i = 0; i < 4; i++) {
        yield return i;
    }
}

因此,yield return返回int,而方法签名要求IEnumerable

在上述情况下,return语句会做什么?是否返回高于收益率的结果?将什么连接到收益率?在上述情况下,return没有多大意义。

因此,我们需要一种在迭代器块中有意义的到return的方法,这就是为什么存在yield break的原因。

当然,您可以使用break来完成它,但是如果您有更多的代码可以执行,那么如何退出函数体呢?把所有东西都包装在一个复杂的if-else块中?我想说,只吃yield break会更好。


您需要区分返回已经存在的IEnumerable实现(也许您将返回一个列表)和匿名迭代器。

不能只使用回车或换行,因为它们是有效的关键字,可以用于其他目的。您也不能单独使用yield,因为您需要有一种方法来指定是返回枚举中的项,还是结束枚举,因此需要yield返回和yield break。