Monthly Archives: April 2009

I love lambda expressions (part 2)!

In previous part we learned about lamda expressions, and ended up with the following example:

List<int> numbers = new List<int> { 1, 7, 16, 23, 41, 66 };
Func<int, bool> funcNumbersSmallerThan25 = n => n < 25;

The delegate funcNumbersSmallerThan25 is compiled into executable code and can be called as follows:

List<int> numbersSmallerThan25 =
numbers.Where(funcNumbersSmallerThan25).ToList();

Expression trees

Now it’s time to introduce another feature called expression trees. An expression tree is a tree structure that contains lambda expressions. To demonstrate, let’s define the delegate as an expression using the following syntax:

Expression<Func<int, bool>> exprNumbersSmallerThan25 = n => n < 25;

Now the delegate exprNumbersSmallerThan25 is no longer compiled to executable code, but instead compiled as data. In order to use it, you have to compile it to IL first:

List<int> numbers = new List<int> { 1, 7, 16, 23, 41, 66 };
Expression<Func<int, bool>> exprNumbersSmallerThan25 = n => n < 25;
var originalDelegate = exprNumbersSmallerThan25.Compile();
List<int> numbersSmallerThan25 = numbers.Where(originalDelegate).ToList();

If you call the ToString() method of the expression:

string lambda = exprNumbersSmallerThan25.ToString();

…you get back the lamda expression of the delegate:

Lambda expression

So what we did was create a delegate exprNumbersSmallerThan25  using the lambda expression ‘n => n < 25’, compiled it to IL code and used it. Instead of writing it using the lamba expression, you can also write it without the lamda expression:

List<int> numbers = new List<int> { 1, 7, 16, 23, 41, 66 };
ParameterExpression n = Expression.Parameter(typeof(int), "n");
Expression body = Expression.LessThan(n, Expression.Constant(25));
Expression<Func<int, bool>> exprNumbersSmallerThan25
= Expression.Lambda<Func<int, bool>>(body, n);
var originalDelegate = exprNumbersSmallerThan25.Compile();
List<int> numbersSmallerThan25 = numbers.Where(originalDelegate).ToList();

Actually this is exactly what internally is going on. Of course you would use lambda expressions because obviously it’s a more clear and shorter way to define an expression.

Expression tree viewer

To visualize expression trees, you can use the Expression Tree Visualizer tool that is part of the Visual Studio 2008 CSharp samples. To use it from Visual Studio, you have to build it first and copy the required DLL so that Visual Studio can use the visualizer:

  • First choose Help | Samples from the Visual Studio 2008 menu, click the ‘local Samples folder’ link and unzip the CSharpSamples/LinqSamples/ExpressionTreeVisualizer solution. 
  • Build the solution and then copy the bindebugExpressionTreeVisualizer.dll assembly to the ‘Visual Studio 2008Visualizers’ directory (to find out the directory on your system, select  Tools | Options | Projects and Solutions | General  from the Visual Studio menu)
  • Restart Visual Studio

You can now test the visualizer by debugging your test project, hovering your mouse above an expression variable and clicking the magnifying glass:

Expression magnifying glass

Click the magnifying glass to view the expression tree:

Expression Tree Viewer

Why use expression trees?

Expression trees provide an efficient data representation of lambda expressions (which are functions, ultimately) – so they are data structures that represent executable code. You can use them to interact with data at a low level: they can be evaluated, parsed and changed during runtime, and transformed to IL code. But why would we want to do such conversions?

To take an example, LINQ2SQL makes heavy use of expression trees. The following is a very simple example of a LINQ2SQL expression:

var employees = from e in db.Employees
where e.City == "Brussels"
select e;

What happens is that this expression is converted into an data structure (expression tree), and then this expression tree is analyzed by the LINQ compiler to decide the best way to convert it to SQL statements, which will be something like:

SELECT [t0].[City], [t0].[EmployeeName]
FROM [db0].[Employees] AS [t0]
WHERE [t0].[City] = @p0

So it’s nothing more than a transformation from expresssion -> data structure -> string representation. The goal of these transformation steps is to generate a data structure that is abstract, so that another process can handle it: the LINQ compiler can analyze and parse it in any way it wants (optimized for data access), or you can pass the same expression tree to some other piece of code that transforms it to something complete different, optimized for something else.

Advertisements

Tips and tricks (2)

The ?? operator is called the null-coalescing operator and is not very well-known, but can be very useful sometimes to define default values for types as in the following example:

int? number1 = null;
// number2 = number1, unless number1 is null, in which case number2 = -1
int number2 = number1 ?? -1;

If number1 is null then number2 will be set to -1, if number1 is not null, number2 will get the value of number1. A useful case where this can be applied is in properties, to guarantee that a collection is initialized:

private List<int> numbers = null;
public List<int> Numbers
{
get { return numbers ?? new List<int>(); }
}

You can even do a number of comparisons in one line of code:

DateTime? dateTime1 = null;
DateTime? dateTime2 = null;
DateTime? dateTime3 = DateTime.Now;
DateTime dateTime = dateTime1 ?? dateTime2
?? dateTime3 ?? DateTime.MinValue;

This obviously avoids a large block of if-then-else statements.

Tips and tricks (1)

The following code is a straightforward example on how to use the event programming model: the main method is the subscriber that will receive ValidationCompleted notifications, and the Validation class is the publisher that publishes the ValidationCompleted event:

class Program
{
static void Main(string[] args)
{
Validation validation = new Validation();
validation.ValidationCompleted +=
new Validation.ValidationHandler(validation_ValidationCompleted);
validation.Execute();
}
static void validation_ValidationCompleted(object sender,
bool succeeded)
{
Console.WriteLine(string.Format("Validation result: {0}", succeeded));
}
}
public class Validation
{
public delegate void ValidationHandler(object sender, bool succeeded);
public event ValidationHandler ValidationCompleted;
public void Execute()
{
// do some validation here
bool validationSucceeded = true;
SignalValidationCompleted(validationSucceeded);
}
protected void SignalValidationCompleted(bool succeeded)
{
if (ValidationCompleted != null)
{
ValidationCompleted(this, true);
}
}
}

If you run this, the result is what you expect:

 Validation output

Notice in the Validation publisher class the test to check for null:

if (ValidationCompleted != null)
{
ValidationCompleted(this, true);
}

You have to do this because when there are no subscribers, the ValidationCompleted event will be null.

A nice trick to avoid the need for this null-test, is to add an empty delegate to the event declaration:

public event ValidationHandler ValidationCompleted = delegate {};

This way, the event will never be null and you can just call it:

protected void SignalValidationCompleted(bool succeeded)
{
ValidationCompleted(this, true); // No null check needed anymore
}

A nice little trick.

I love lambda expressions (part 1)!

In the beginning, you are nervous, not sure and even afraid. Slowly you get used to it by experimenting and finally you can’t live without it anymore. To avoid confusion, I’m talking about lamda expressions here.  To prove my point, let’s first go back into time.

If we would need to filter out a list of numbers to get all the numbers smaller than 25, following code does that fine:

List<int> numbers = new List<int> { 1, 7, 16, 23, 41, 66 };
List<int> numbersSmallerThan25 = new List<int>();
foreach (int number in numbers)
{ if (number < 25) { numbersSmallerThan25.Add(number); } }

Using predicate delegates

Of course, we can do a lot better, by creating a method that checks if a passed number is smaller than 25, and passing this method as a parameter to the FindAll method of the list:

static void Main(string[] args)
{
List<int> numbers = new List<int> { 1, 7, 16, 23, 41, 66 };
List<int> numbersSmallerThan25 =
numbers.FindAll(MatchNumberSmallerThan25);
}
private static bool MatchNumberSmallerThan25(int number)
{
return number < 25;
}

Here we make use of predicate delegates. A predicate delegate is a method that returns true or false. In this case we define a MatchNumberSmallerThan25 method, which returns true if the passed number is smaller than 25. Now we can pass this predicate to the FindAll method of the generic list. As a result, the FindAll method executes the MatchNumberSmallerThan25  method for each item in the generic list. For each call that returns true, the collection item is added to the returning collection of the FindAll method.

Using anonymous methods

This already seems a lot better, however, we still have to create private methods for every case we have, methods that we probably never reuse. So we could improve this by using anonymous methods:

List<int> numbers = new List<int> { 1, 7, 16, 23, 41, 66 };
List<int> numbersSmallerThan25 = numbers.FindAll(
delegate(int number) { return number < 25; } );

In this example we are passing an anonymous inline piece of code as a predicate delegate to the FindAll method, which does exactly the same as the MatchNumberSmallerThan25 method. This offers us a number of advantages: no need to clutter your code with private named methods, the code is where it is used, no need to specify the return type (it is inferred from the signature of the delegate type to which the anonymous method is being cast to) and you can refer to the outer variables from within the anonymous method.

Using lambda expressions

As the title of this blog suggests, we still have a way to improve the code above. So let’s dot that:

static void Main(string[] args)
{
List<int> numbers = new List<int> { 1, 7, 16, 23, 41, 66 };
List<int> numbersSmallerThan25 = numbers.FindAll(n => n < 25);
}

Did you notice the amount of code we have left? And this is all thanks to the beloved lambda expressions! At first it seems a bit cryptic, so what is a lambda expression? It’s nothing more than an anonymous method used to create a delegate, and that takes takes the form:

argument-list => expression

In our example, the lambda expression consists of an argument named ‘n’ (which is implicitely typed as an integer), then the lambda operator ‘=>’, followed by an expression ‘n < 25’.

You could read it as: ‘There’s a method that takes one parameter n and a list of integers; and it returns every number from that list that is smaller than 25 ‘. This lambda expression is then passed to the FindAll method of the generic collection. Actually, this lambda expression is a very small, compact, anonymous method that is another way of writing an anonymous method, which is also more readable and verbose.

A closer look

If we look at the FindAll signature, we see that it expects a parameter of type Predicate<T>, and because we are applying it to a list of integers, it has to be of type Predicate<int>. So we could explicitely create and use such predicate as follows:

List<int> numbers = new List<int> { 1, 7, 16, 23, 41, 66 };
Predicate<int> predNumbersSmallerThan25 = n => n < 25;
List<int> numbersSmallerThan25 = numbers.FindAll(predNumbersSmallerThan25);

However, FindAll is a .NET 2.0 method, and the preferred way is using the .NET 3.5 Where method, which expects a Func<T1, TResult> parameter. T1 is the type of the parameter (which is int) and TResult is the type of the returned value (which is bool). So we end up with the following code, which has exact the same results as the previous code:

List<int> numbers = new List<int> { 1, 7, 16, 23, 41, 66 };
Func<int, bool> funcNumbersSmallerThan25 = n => n < 25;
List<int> numbersSmallerThan25 =
numbers.Where(funcNumbersSmallerThan25).ToList();

Other examples

Now that you have fallen in love with lambda expressions too, some other examples:

// Add 5 to every number in the collection
List<int> numbersAdded5 = numbers.ConvertAll(n => n + 5);
// Sort list descending (lambda expression with two arguments!)
numbers.Sort( (a,b) => b-a );
// Groups collection of numbers into two groups containing
// odd or even numbers
var grouped = numbers.GroupBy(n => n%2==0);

Note the ‘var’ keyword in the last example. It means that the compiler will infer the type for you, it does not mean that it’s some kind of variant data type that can change. In this case, the grouped variable will always be of type ‘System.Linq.GroupedEnumerable<int,bool,int>’, because that is the return type of the GroupBy method.

There’s more to learn about lambda expressions… in the second part!