Friday, August 22, 2008

How to Replace Nested foreach Loops With a LINQ Expression

The following nested foreach loops search for all test methods in an assembly:

IEnumerable<String> tests = new List<String>();

Assembly a = Assembly.LoadFrom(dll);
Type[] types = a.GetTypes();

foreach (Type type in types)
{
if (type.IsDefined(typeof (TestClassAttribute), true))
{
MethodInfo[] methods = type.GetMethods();

foreach (MethodInfo method in methods)
{
if (method.IsDefined(typeof (TestMethodAttribute), true))
{
tests.Add(method.Name);
}
}
}
}

return tests;
Using LINQ this function can be rewritten in a very compact yet very readable form:
return from type in Assembly.LoadFrom(dll).GetTypes()
where type.IsDefined(typeof (TestClassAttribute), true)
from method in type.GetMethods()
where method.IsDefined(typeof (TestMethodAttribute), true)
select method.Name;
The first from - where part selects all types which are test classes. The second from where part walks through this list and searches for all methods which are test methods. From these methods the method name is added to the return value.

Note that in LINQ you can combine from - where clauses to generate nested queries.
Post a Comment