thzinc

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.