Yield Return Many?
This is a somewhat frequently requested feature that C# does not support. See this Connect item for details:
http://connect.microsoft.com/VisualStudio/feedback/details/256934/yield-return-to-also-yield-collections
The proposed syntax is usually something like:
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();
}
If you are interested in playing with a C#-like language that supports this feature, take a look at Cω:
http://research.microsoft.com/en-us/um/cambridge/projects/comega/
You might also want to read this paper on the feature by the implementors of Cω:
http://research.microsoft.com/en-us/projects/specsharp/iterators.pdf
If you're interested in a non-C#-like language that supports this feature, take a look at the "yield!" feature of F#. (I just love that the name of the feature is "yield!")
Even if you are not interested in the theoretical stuff, it sounds like you face this situation as a practical problem. You should also read Wes Dyer's article on techniques for efficiently doing this sort of nested iteration without "yield foreach":
http://blogs.msdn.com/b/wesdyer/archive/2007/03/23/all-about-iterators.aspx
No, there isn't, unless you completely replace every yield return
with a single return
statement using LINQ.
For example:
return someSet
.Concat(someOtherSet.SelectMany(s => FindSingle(context, s));
With C# 7.0, local functions are allowed, which enables us to have a fairly neat approach
IEnumerable<T> FlatEnumerable(){
IEnumerable<IEnumerable<T>> NestedEnumerable(){
yield return myEnumerable1;
yield return myEnumerable2;
}
return NestedEnumerable().SelectMany(e => e);
}
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/local-functions
Use Enumerable.SelectMany
:
return subSelectors.SelectMany(subselector => FindSingle(context, subSelector));
This only works if you don't have any other yield return statements in your method.