C# yield return 仅适用于 IEnumerable<T>?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1070974/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 07:32:46  来源:igfitidea点击:

yield return works only for IEnumerable<T>?

c#.netienumerable

提问by Jader Dias

Can I use yield returnwhen the return type is an IGrouping<TKey, TElement>or an IDictionary<TKey, TValue>?

yield return当返回类型是 anIGrouping<TKey, TElement>或 an时我可以使用IDictionary<TKey, TValue>吗?

采纳答案by Marc Gravell

yield returnworks for exactly 4 cases:

yield return适用于 4 种情况:

  • IEnumerable
  • IEnumerable<T>
  • IEnumerator
  • IEnumerator<T>
  • IEnumerable
  • IEnumerable<T>
  • IEnumerator
  • IEnumerator<T>

This is because it has to build a state machine internally; a dictionary (etc) wouldn't be possible with this. You can of course just returna suitable type instead.

这是因为它必须在内部构建一个状态机;用这个不可能有字典(等)。您当然可以只return使用合适的类型。

回答by Joel Martinez

nope, just ienumerable :-)

不,只是数不清:-)

回答by Andy

I don't think so. While the documentationdoesn't exactly spell it out, the way it is worded implies that it can only be used when the return type of the method is either IEnumerableor IEnumerable<T>. You might be able to write a class that implements IGroupinggiven an IEnumerable(that would be returned from your method using yield return), but that's about the only option really.

我不这么认为。虽然文档没有完全说明它,但它的措辞方式暗示它只能在方法的返回类型为IEnumerableor 时使用IEnumerable<T>。您可能能够编写一个实现IGrouping给定 an的类IEnumerable(它将从您的方法中使用 返回yield return),但这实际上是唯一的选择。

回答by Andrew Hare

No, because an iterator block is simply a state machine built on your behalf by the compiler. This feature allows you to "yield" and item as a portion of a sequence.

不,因为迭代器块只是编译器代表您构建的状态机。此功能允许您“产生”和项目作为序列的一部分。

If the return type was other than IEnumerable<T>(like IDictionaryfor example) the compiler would have to generate methods to implement that interface and at that point it wouldn't make much sense because you would be working with a collection rather than a sequence.

如果返回类型不是IEnumerable<T>IDictionary例如),编译器将不得不生成实现该接口的方法,此时它没有多大意义,因为您将使用集合而不是序列。

回答by Timothy Carter

You could however return IEnumerable<KeyValuePair<K,V>>that would be similar to a dictionary. You would then yield return KeyValuePairs. You could even wrap this with another method that creates a dictionary out of the return. The only thing the first method would not guarantee is uniqueness in the keys.

但是IEnumerable<KeyValuePair<K,V>>,您可以返回类似于字典的内容。然后您将产生返回 KeyValuePairs。您甚至可以使用另一种方法将其包装起来,该方法根据返回值创建字典。第一种方法唯一不能保证的是键的唯一性。

回答by jason

Answer: No. A yield returnstatement can be used only if the return type is IEnumerator, IEnumerator<T>, IEnumerable, or IEnumerable<T>.

答:编号Ayield return语句只能如果返回类型为使用IEnumeratorIEnumerator<T>IEnumerable,或IEnumerable<T>

From §8.14 of the C# 3.0 spec:

来自C# 3.0 规范的第8.14 节:

The yield statement is used in an iterator block (§8.2) to yield a value to the enumerator object (§10.14.4) or enumerable object (§10.14.5) of an iterator or to signal the end of the iteration.

yield 语句在迭代器块(第 8.2 节)中用于为迭代器的枚举器对象(第 10.14.4 节)或可枚举对象(第 10.14.5 节)产生一个值,或表示迭代结束。

From §10.14.4:

从第 10.14.4 节开始:

An enumerator object has the following characteristics:

枚举器对象具有以下特征:

  1. It implements IEnumeratorand IEnumerator<T>, where Tis the yield type of the iterator.
  1. 它实现了IEnumeratorand IEnumerator<T>,其中T是迭代器的产量类型。

[...]

[...]

From §10.14.5:

从第 10.14.5 节开始:

An enumerable object has the following characteristics:

可枚举对象具有以下特点:

  1. It implements IEnumerableand IEnumerable<T>, where Tis the yield type of the iterator.
  1. 它实现了IEnumerableand IEnumerable<T>,其中T是迭代器的产量类型。

[...]

[...]

回答by Daniel Earwicker

Just call the iterator method and chain ToDictionaryor GroupByafter it, and you have much the same thing. Put that in a one-line wrapper method if you need to call it like that from several places.

只需调用迭代器方法和链ToDictionaryGroupBy在它之后调用,你就会得到很多相同的东西。如果您需要从多个地方像这样调用它,请将其放在单行包装器方法中。