Sayse
Sayse

Reputation: 43300

Generic All Controls Method

Couldn't think of a better title so appologies..

I'm trying to convert this method, which will retrieve all child controls of a form, to be an extension method as well as accept interfaces as inputs. So far I am up to

public IEnumerable<Control> GetAll<T>(this Control control) where T : class
{
    var controls = control.Controls.Cast<Control>();

    return controls.SelectMany(ctrl => GetAll<T>(ctrl))
                                .Concat(controls)
                                .Where(c => c is T);
}

which works fine except I need to add OfType<T>() when calling it to get access to its properties.

e.g (this == form)

this.GetAll<IMyInterface>().OfType<IMyInterface>()

I'm struggling to make the return type into a generic return type IEnumerable<T>, so that I don't have to include a OfType which will just return the same result but cast correctly.

Anyone have any suggestions?

(Changing return type to IEnumerable<T> causes the Concat to throw

Instance argument: cannot convert from 'System.Collections.Generic.IEnumerable<T>' to 'System.Linq.ParallelQuery<System.Windows.Forms.Control>'

Upvotes: 3

Views: 1146

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1500575

The problem is that Concat would want an IEnumerable<T> as well - not an IEnumerable<Control>. This should work though:

public static IEnumerable<T> GetAll<T>(this Control control) where T : class
{
    var controls = control.Controls.Cast<Control>();

    return controls.SelectMany(ctrl => GetAll<T>(ctrl))
                                .Concat(controls.OfType<T>()));
}

Upvotes: 3

Related Questions