Question

 public static IEnumerable<UIElement> Traverse(this UIElementCollection source)
    {
        source.OfType<Grid>().SelectMany(v => Traverse(v.Children));
        //This is the top level.
        foreach (UIElement item in source)
        {
            yield return item;
        }
    }

This never returns anything recursively. I have been around the houses. The Linq chain should call back into the function/extension method but never does. The line does nothing as far as I can tell!

Was it helpful?

Solution 3

 public static IEnumerable<UIElement> Traverse(this UIElementCollection source)
    {
        //This is the top level.
        foreach (UIElement item in source.OfType<Grid>().SelectMany(v => Traverse(v.Children)).Concat(source.Cast<UIElement>()))
        {
            yield return item;
        }
    }

This has the desired result, not sure it is optimal though!

OTHER TIPS

You are not doing anything with the result of the expression and probably the lazy evaluation is not enforced. If you really want to ignore the result of the expression, at least try adding ToArray() at the end ;) That should enforce the evaluation and recursively call your Traverse function.

Advantage of Bojan's solution (provided that's what you really want because it returns a different result than your initial one), is that the actual evaluation responsibility is shifted to the client of the Traverse method. Because in your case these are in-memory queries anyway, it is not that big of a difference, but if these were database queries there is a more significant performance penalty (count of actual database queries) for putting ToArray somewhere.

The recursive call is never executed, as you never use the result of SelectMany. You can make this method lazy, and let the clients evaluate it when needed by combining the result of SelectMany with the current source. Perhaps something like this would do the job (not tested):

public static IEnumerable<UIElement> Traverse(this UIElementCollection source)
{
    var recursive_result = source.OfType<Grid>().SelectMany(v => Traverse(v.Children));
    return recursive_result.Concat( source.Cast<UIElement>() );
}   
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top