产量回报很多?
我发现自己对IEnumerables进行了大量的研究,以便我可以返回每个结果。 有没有办法来压缩这样的东西
foreach (var subSelector in subSelectors) { foreach (var node in FindSingle(context, subSelector)) yield return node; }
去除内部的foreach?
不,没有,除非你完全用一个单一的return
语句使用LINQ来取代每个yield return
。
例如:
return someSet .Concat(someOtherSet.SelectMany(s => FindSingle(context, s));
这是C#不支持的频繁请求function。 有关详情,请参阅此连接项目:
build议的语法通常是这样的:
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(); }
如果您有兴趣使用支持此function的类似C#的语言,请查看Cω:
http://research.microsoft.com/en-us/um/cambridge/projects/comega/
您可能还想阅读关于Cω的实现者的这篇文章:
en-us/projects/specsharp/iterators.html
如果您对支持此function的非C#语言感兴趣,请查看“yield”。 F#的function。 (我只是喜欢这个function的名字是“yield!”)
即使你对理论上的东西不感兴趣,这听起来像是你面对这种情况是一个实际问题。 你还应该阅读Wes Dyer关于技术的文章,以便在没有“yield foreach”的情况下高效地进行这种嵌套迭代:
http://blogs.msdn.com/b/wesdyer/archive/2007/03/23/all-about-iterators.aspx
使用Enumerable.SelectMany
:
return subSelectors.SelectMany(subselector => FindSingle(context, subSelector));
这只有在您的方法中没有任何其他的yield return语句时才有效。
你可以把你的方法分成两部分。 鉴于这些扩展方法:
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); } }
用Eric Lippert的例子来说就是:
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,而外部方法只需要使这个结果变平。
使用Linq的力量!
return subSelectors.SelectMany(s => FindSingle(context, s));