Expression trees, delegates, functors how and why to use them

As of two weeks ago I’ve had the privilege to start doing some development work in a project where a lot of expression trees are used and most classes have at least one implementation of a Func delegate. There’s nothing wrong with that, as it’s something which dates from the .NET 3.0 era if I’m not mistaken, so every .NET 3.5 certified/professional developer should know the existence of them. Downside is, if your only real experience with the matter is reading them up in a text book, there’s a big chance you have forgotten on how and why to use it. Most importantly, what it does.

Lucky for me I’ve done a WP7 project in the recent past where I became a bit more familiar with the Func and Action delegates. Still, I got the feeling I don’t know half of the stuff you can use it for. This became even more clear 2 weeks ago when I started on this project. I could read the code and visualize what the code was doing, but couldn’t implement new features in a reasonable amount of time. Lucky for me I’m working in a team with several other developers who have (a lot) more experience on the subject explained what I needed to do. While listening to them I thought “Hey, this is easy, why didn’t I think of it!” and started implementing the new code.

I think this is the tricky part of developing, it appears to be so easy if it’s explained to you, but hard to think of if you got no real experience with the matter.

Just to be sure, I did small search on what a Func and an Action represented. I also needed to do a sarch on something completely new to me, an Expression tree. It’s probably me, but I can’t remember reading up on anything called like that studying for my exams (70-536, 70-562 & 70-564). This probably means I forgot it even existed and didn’t have any questions on it in the exams (phew!).

Reading up on the matter, it appears an Expression tree is just a fancy word for an ‘uncompiled piece of code’. You can modify the body of the tree so it behaves just the way you want it. After compiling the piece of code you can invoke it with the parameters you want. Quite a powerful feature for sure, if you know how to handle it. A quite familiar expression tree (if you’ve done some database developing with LINQ) is the IQueryable. You can extend the ‘body’ of the method by calling a lot of lambda’s on it and it get’s compiled when you need to retrieve the data of the collection. That’s the main reason it’s better to use an IQueryable instead of an IEnumerable when creating a query.

While browsing through the code my mind blown by the following:

Expression<Func<IViewModel, object>>

I thought I understood the delegates, but this was above my comprehension. Luckily for me I’m not the only one who is struggling with it. Searching for it led me to StackOverflow and I especially like the following comment:

Expression<Func<…» is an expression tree which represents the original source code (it is stored in a tree-like data structure that is very close to the original C# code). In this form, you can analyze the source code and tools like LINQ to SQL can translate the expression tree (source code) to other languages (e.g. SQL in case of LINQ to SQL, but you could also target e.g. JavaScript).

Func<…> is an ordinary delegate that you can execute. In this case, the compiler sompiles the body of the function to intermediate language (IL) just like when compiling standard method.

Developing the WP7 app was my first real experience with these delegate methods. It is awesome what you can do, just by passing a ‘method’ as a parameter to another layer (or class) in your design. With the introduction of expression trees you can even pass methods to different pieces of code and modify the body of it, depending on the situation. Now that’s even more awesome!

You might have guessed it, I’m starting to become a big fan of these features. The main reason for this post is to remind me on how these things work and what’s the difference between them.

Next up are some code examples which will try to make it clear what the different kind of delegates mean and how they can be used. There’s a different blogpost I found (via StackOverflow) which also does a good job describing the differences between the different delegates.

First up, the Action.

If you see an Action defined in your code, it just means there’s a method specified which returns void. You put in a parameter of the type T and some magic happens. An example:

public void DemoMethod()
{
	Action<string> printMessage = ShowMessage;
	printMessage("Hello World");
}
private void ShowMessage(string message)
{
	Response.Write(message);
}

Now, this example isn’t really meaningful, but this can also be used in more advanced scenario’s of course. It’s also possible to add more input parameters, so you could also use an Action<T1, T2, T3, T4,..>. I’ve read somewhere it goes up until 16 parameters, which most of the time will be enough.

Second, Func

As the Action isn’t really exciting (I haven’t seen any advanced implementations with it), let’s move on to the Func. This one is used a lot in LINQ and lambda expressions. First, let’s cover the basics. A Func represents a method with one or more input parameters and an output of the type TResult.

The method below is a Func, just written in the old fashioned way:

public bool IsThisTextLong(string text)
{
	if(text.Length > 100)
		return true;
	return false;
}

Just as with an Action, you can put this logic in a variable and use it there. This will look like this:

Func<string   , bool> longText = IsThisTextLong;
bool isThisALongText = longText("Wow, this is a really short text, is it not?");

The variable isThisALongText will get the value of false. This looks kind of cool, but when can you use such a thing? I’ve used it myself to do some UI manipulation in the business logic layer. I modified some values and they needed to be shown in the UI.

A fairly bad example (BusinessLogic needs to be in a different layer and nothing is done with the output string), but I think you know what I mean:

public MainMethod()
{
	BusinessLogic(Write);
}

public string Write(string text)
{
	Console.WriteLine(text);
	return text;
}

public void BusinessLogic(Func<string, string> func)
{
	func("Something for the console.");
}

This could probably be handled in a much better and cleaner way (eventhandlers and callbacks perhaps), but I wanted to use a Func<T, TResult> as I had never used that before and wanted to see how it worked.

When using a lambda expression in your code, you are also using Func<T, TResult> without even knowing it. Look at this Where-clause I placed on a string:

string hello = "Wow, Unicorns are in the house!";
var filteredHello = hello.Where(c =>
            	{
            		if (c == 'i')
            			return true;
            		return false;
            	});

This is a lambda expression on a string, but if you take a look at the tooltip, you’ll see there’s a Func<char, bool> defined in it:

image

As a string is just a collection of characters, you can check every character in the string to see if they match your criteria. If it matches, you need to return a true, if not false. In the example above the variable filteredHello will be a string containing only i-characters, filtered from the hello-string.

It’s all quite easy to understand when checking out the above examples, but most of the time things aren’t this simple in real life.

Expression trees

Just when I thought I understood the delegates I saw something which blew my mind, it was the expression tree mentioned earlier:

Expression<Func<IViewModel, object>>

The developer which showed me this was like

Yeah, you need to create some methods blah blah blah expressions, blah blah blah, check them, blah blah blah. While he was talking all I thought was “.oooookaaaay.let me check Bing for it._”.

I knew I had to do something with an IViewModel and something needed to come out of it, but what was the Expression for, how is that used and what does it do? As written earlier in this post, I’ve read up on the subject and know a bit on how to use these expression trees.

As lambda expressions are represented as Func<T, TResult>’s, it’s easy to see a Func<IViewModel, object> is a lambda expression. Also, an expression is just some piece of uncompiled code, I didn’t need to do anything special with it and could call the method like this:

public void Validate<TViewModel>(params Expression<Func<TViewModel, object>>[] optionalParameters)
{
	//Some validation logic is here.
}
public void ViewModelExpressionCalling()
{
	var dummyViewModel = new DummyViewModel();
	Validate<dummyviewmodel>(d => dummyViewModel.DummyParameter1, d => dummyViewModel.DummyParameter2);
}

Now, this looks a lot easier as opposed to the very advanced looking parameter. The return type is an object (more specific, a string) and the input is a DummyViewModel (because of the generic).

Because you are passing it as an expression, you can use the local variables out-of-scope. That’s because if you use a local variable in an expression tree, it doesn’t get disposed when the scope ends, it keeps in memory until the expression is disposed (really awesome!).

The expression tree above just returns a property of a local view model, that is, if you compile it. It’s good to know that before you can use an expression tree you need to compile it, remember, it’s uncompiled. After it’s compiled you can call the Invoke method on it. What’s cool about this is you can pass any DummyViewModel variable in the Invoke method and it’ll use this in the Func. The variable d would be the variable we’d pass in the Invoke method.

Another plus-side of using expression trees, I was able to check which property was passed in the above example. I needed to check if a specific property was supplied in the collection, if so, it needed validating. Because of this implementation I was able to check out the Body of the expression tree and use some reflection on it. Using this it was fairly easy to discover which properties were defined and in need of validation.

I could go on writing on how amazing expression trees are and give examples on how useful they are in real life projects, but I’ll stop for now. Just one more thing for me to write: Try out expression trees, they are awesome!


Share

comments powered by Disqus