【发布时间】:2010-11-07 10:39:35
【问题描述】:
当返回类型为IGrouping<TKey, TElement> 或IDictionary<TKey, TValue> 时,我可以使用yield return 吗?
【问题讨论】:
标签: c# .net ienumerable
当返回类型为IGrouping<TKey, TElement> 或IDictionary<TKey, TValue> 时,我可以使用yield return 吗?
【问题讨论】:
标签: c# .net ienumerable
不,只是 ienumerable :-)
【讨论】:
我不这么认为。虽然documentation 没有准确地拼出它,但它的措辞方式暗示它只能在方法的返回类型为IEnumerable 或IEnumerable<T> 时使用。给定IEnumerable(将使用yield return 从您的方法返回),您也许可以编写一个实现IGrouping 的类,但这实际上是唯一的选择。
【讨论】:
不,因为迭代器块只是编译器为您构建的状态机。此功能允许您“让步”并将项目作为序列的一部分。
如果返回类型不是IEnumerable<T>(例如IDictionary),编译器必须生成方法来实现该接口,此时它没有多大意义,因为您将使用集合而不是序列。
【讨论】:
但是,您可以返回类似于字典的 IEnumerable<KeyValuePair<K,V>>。然后你会产生返回 KeyValuePairs。你甚至可以用另一种从返回中创建字典的方法来包装它。第一种方法唯一不能保证的是键的唯一性。
【讨论】:
yield return 仅适用于 4 种情况:
IEnumerableIEnumerable<T>IEnumeratorIEnumerator<T>这是因为它必须在内部构建一个状态机;字典(等)是不可能的。你当然可以只用return 一个合适的类型来代替。
【讨论】:
答案:不可以。只有当返回类型为IEnumerator、IEnumerator<T>、IEnumerable 或IEnumerable<T> 时,才能使用yield return 语句。
来自C# 3.0 spec 的§8.14:
yield 语句用于迭代器块(第 8.2 节)中,为迭代器的枚举器对象(第 10.14.4 节)或可枚举对象(第 10.14.5 节)生成一个值,或发出迭代结束的信号.
从 §10.14.4:
枚举器对象具有以下特征:
IEnumerator 和IEnumerator<T>,其中T 是迭代器的产量类型。[...]
从 §10.14.5:
可枚举对象具有以下特征:
IEnumerable 和IEnumerable<T>,其中T 是迭代器的产量类型。[...]
【讨论】:
只需调用迭代器方法并在其后链接ToDictionary 或GroupBy,您就会得到很多相同的东西。如果您需要从多个地方这样调用它,请将其放入单行包装器方法中。
【讨论】: