Combining @Jordao's answer and the fact that C#7 contains local functions, as @Oskar mentiond I think the following would be the "updated" answer:
public static IEnumerable<T> PreorderTraversal<T>(this BinaryTree<T> root)
{
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();
}
return PreorderTraversalMulti.Concat( PreorderTraversalMulti(root).Flatten());
}
I used this for a different reason - to get all files up to 3 stages inside and finalized with this function:
public static IEnumerable<FileInfo> EnumerateFiles(DirectoryInfo sourceFolder, string pattern, int steps2Enter, int currStep = 0, int maximumNumFiles = 800)
{
int total = 0;
IEnumerable<FileInfo> NestedFunc()
{
if (currStep > steps2Enter) yield break;
if (sourceFolder == null) yield break;
foreach (var file in sourceFolder.GetFiles(pattern, SearchOption.TopDirectoryOnly))
{
if (total++ > maximumNumFiles) yield break;
yield return file;
}
}
return NestedFunc().Concat(sourceFolder.EnumerateDirectories().SelectMany(s => EnumerateFiles(s, pattern, steps2Enter, currStep + 1, maximumNumFiles)));
}
So yes - I'm still waiting for some syntatic sugar which will enable writing
yield return foreach...