Lamda Expressions and Tests

One of tests I am currently writing for TestListGenreator is checking to see if the function that gets a list of all the Tests in a DLL returns the right amount of category associations. The tests come back as a Dictionary<MethodInfo, HashSet<string>> collection. Counting the number of tests returns is easy:

Dictionary<MethodInfo, HashSet<string>> results = ReflectionHelper.GetTestsFromAssembly(“TestListGenerator.Tests.TestSubject.dll”);
int numberOfTests = results.Count;

However, counting the total amount of hashset entries is a little more difficult. In the past, I would have written something like this

int count = 0;
foreach(HashSet <string> value in results.Values)
  count += value.Count;

It works, but it just adds to the mess that is already my test cases logic. I am a great believer in chunking; however, coming from a background in Perl, I am fully aware that there is a point where chunking (writing code succinctly as possible) becomes obsfication. I think Lamda Expressions walk a narrow line in this regard (especially when it comes to understanding the method signatures!). Here’s the above code summed up in a lambda expression:

int count = results.Sum(f => f.Value.Count);

The first thing to note is the .Sum() function. You would have noticed that code completion on generic collection objects now list a whole bunch of methods that have the following icon in front of them: Extension Method. These are extension methods – I’ll cover them in a later blog post. For now, just view them as extra methods. 

For example, Sum, will sum all the objects in the collection. But wait! It takes in this weird “Func<KeyValuePair<keyObject, valueObject>, int> selector” parameter. What is this? Well, it’s a delegate signature. The “Func” means delegate, and what appears inside the <> is a list of parameters. The last parameter is always what the function should return. So, in this case, you need to define a function that takes in a KeyValuePair and returns an int. Then the Sum function will do all the work of adding all the integers you return.

Fortunately, .net allows you to define delegates inline. So you can do the following: kvp => kvp.Values.Count. What this means is that kvp is your name for the KeyValuePair<keyObject, valueObject> parameter, and what follows the => is what you want to do with it. So, the Sum object, calls kvp.Values.Count for each object in the dictionary, and then sums up all those integers.

Post a comment or leave a trackback: Trackback URL.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: