Think LINQ – .SelectMany()
I recently came across a beautiful example of .SelectMany()
used to find all types that implement a particular interface in all currently loaded assemblies. With minor alterations, here is how I used it:
IEnumerable<Type> types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).Where(t => typeof(MyInterface).IsAssignableFrom(t) && t.IsClass && !t.IsAbstract);
You might ask, “What is .SelectMany()
?” In a phrase, it is a list-of-lists flattener. Specifically, it is a LINQ extension method that iterates over an IEnumerable<TSource>
executing an anonymous method that returns an IEnumerable<TElement>
. Each of the IEnumerable<TElement>
s that result are combined into a single IEnumerable<TElement>
that may be used.
In the example above, there is an IEnumerable<Assembly>
returned from AppDomain.CurrentDomain.GetAssemblies()
. Each Assembly
has a .GetTypes()
method that returns IEnumerable<Type>
. Ultimately, I want just one IEnumerable<Type>
to iterate through and perform my .Where()
filtering. By using .SelectMany()
, I can iterate over the assemblies and produce a combined list of types.