我發現我自己對IEnumerables進行了大量的研究,以便我可以返回每個結果。有沒有辦法像這樣壓縮產量回報多?
foreach (var subSelector in subSelectors)
{
foreach (var node in FindSingle(context, subSelector))
yield return node;
}
要刪除內部的foreach?
我發現我自己對IEnumerables進行了大量的研究,以便我可以返回每個結果。有沒有辦法像這樣壓縮產量回報多?
foreach (var subSelector in subSelectors)
{
foreach (var node in FindSingle(context, subSelector))
yield return node;
}
要刪除內部的foreach?
不,不存在,除非您完全使用LINQ將單個return
聲明全部替換爲yield return
。
例如:
return someSet
.Concat(someOtherSet.SelectMany(s => FindSingle(context, s));
return subSelectors.SelectMany(subselector => FindSingle(context, subSelector));
這隻能如果你沒有在你的方法的任何其他收益率return語句。
是的......但是在那之後你不能再產生任何東西。 – mpen 2010-10-03 23:35:19
這是C#不支持的有點頻繁的功能。有關詳細信息,請參閱本連接項目:
所提出的語法通常是這樣的:
public static IEnumerable<T> PreorderTraversal<T>(this BinaryTree<T> root)
{
if (root == null) yield break;
yield return root.Item;
yield foreach root.Left.PreorderTraversal();
yield foreach root.Right.PreorderTraversal();
}
如果您有興趣與支持此功能類似C#語言播放,採取看看C-Omega:
http://research.microsoft.com/en-us/um/cambridge/projects/comega/
你也可能需要閱讀對T本文他功能,通過C-Omega的實現者:
http://research.microsoft.com/en-us/projects/specsharp/iterators.pdf
如果你有興趣在支持此功能的非類似C#語言,看看在「屈服!」 F#的功能。 (我只是喜歡該功能的名稱是「屈服!」)
即使你對理論的東西不感興趣,這聽起來像你面臨這種情況作爲一個實際問題。你也應該閱讀韋斯·戴爾對技術的文章,有效地做這樣的嵌套迭代不「屈服的foreach」:
http://blogs.msdn.com/b/wesdyer/archive/2007/03/23/all-about-iterators.aspx
我以爲Comega已經集成到C#中,所以他們停止開發它。它是否繼續爲未來的C#版本帶來新的想法? – 2010-10-04 17:03:53
@Joan:來自C-omega的一些想法已經被整合到C#中,其中一些還沒有。無論研究還是發展,我都不知道。 – 2010-10-04 18:48:10
我認爲只是'收益'聽起來會更好。感謝你的回答!這很有趣。 – mpen 2010-10-06 09:08:12
您可以打破你的方法一分爲二。鑑於這些擴展方法:
public static class MultiEnumerableExtensions {
public static IEnumerable<T> Pack<T>(this T item) {
yield return item;
}
public static IEnumerable<T> Flatten<T>(
this IEnumerable<IEnumerable<T>> multiList) {
return multiList.SelectMany(x => x);
}
}
而且使用埃裏克利珀的example,就變成這樣:
public static class BinaryTreeExtensions {
public static IEnumerable<T> PreorderTraversal<T>(this BinaryTree<T> root) {
return PreorderTraversalMulti(root).Flatten();
}
private static IEnumerable<IEnumerable<T>> PreorderTraversalMulti<T>(
this BinaryTree<T> root) {
if (root == null) yield break;
yield return root.Item.Pack(); // this packs an item into an enumerable
yield return root.Left.PreorderTraversal();
yield return root.Right.PreorderTraversal();
}
}
內方法產生的T,而不是TS的枚舉接口,與外部方法只需要扁平化這一結果。
對於少量語法糖來說,看起來像是一個很大的開銷。我欣賞這個建議,但它*很有趣。 – mpen 2010-10-06 09:06:54
有可能是一個門檻,它使用它是有意義的。可能如果你的方法中有多個「foreach yield」。我認爲埃裏克的例子很少有資格。其他人可能會認爲不然。 – 2010-10-06 13:11:44
使用Linq的力量!
return subSelectors.SelectMany(s => FindSingle(context, s));
這已被問了很多次,應該合併。搜索「yield multiple enumerable」 – mafu 2010-10-03 23:35:00
@mafutrct:*沒有找到「yield multiple enumerable」的結果。*您能舉一個例子嗎? – 2010-10-03 23:40:42
這是我發現(授予,與不同的搜索短語):http://stackoverflow.com/questions/2055927/ienumerable-and-recursion-using-yield-return,http://stackoverflow.com/questions/ 1824934/rewrite-this-foreach-yield-to-a-linq-yield,http://stackoverflow.com/questions/1270024/nested-yield-return-with-ienumerable。但是,我沒有找到我正在尋找的問題,這個問題確切地解釋了要求的內容。我還記得前一段時間曾問過這個問題......我會嘗試在我的Q列表中查看它。 – mafu 2010-10-04 09:56:22