C# Refactoring Adventures with Lambda Expressions

I’ve been playing around with delegates and lambda expressions, and thought I would note down what I had learned (this is a programming notebook, after all).

    class Program
    {
        delegate int IntFunc(int a, int b);

        static void Main(string[] args)
        {
            IntFunc add = new IntFunc(delegate(int a, int b) { return a + b; });
            Console.WriteLine(add(1, 2));
        }
    }

I am particularly interested in how we can improve the following line with lambda expressions and a little syntactic sugar:

IntFunc add = new IntFunc(delegate(int a, int b) { return a + b; });

So, let’s start by turning it into a lambda-expression:

IntFunc add = new IntFunc((a, b) => { return a + b; });

Here, we say “parameters a and b of our deletegate ‘go to’ (=>) our block of functionality, which is defined in the {} braces.

But we don’t actually need the curly braces, or the return for that matter, as the lambda expression will infer this. So, we can reduce the expression down to the following:

IntFunc add = new IntFunc((a, b) => a + b);

However, looking at the original statement, we realise that the new IntFunc isn’t necessary either. It could have read:

IntFunc add = delegate(int a, int b) { return a + b; };

So, our lambda expression reduces down even further:

IntFunc add = (a, b) => a + b;

Marvellous! It also explains to me quite nicely how lambda expressions syntax derives from the equivalent delegate syntax.

But, we’ve not finished here. Take our delegate type:

delegate int IntFunc(int a, int b);

C# already has an in-built type func<> to save us from such declarations. We can dispense with the delegate line completely when we recognise that we have two inputs of type int and one output of type int.

Our final class looks like this

    class Program
    {
        static void Main(string[] args)
        {
            Func add = (a,b) => a + b;
            Console.WriteLine(add(1, 2));
        }
    }

Lovely!

Leave a Reply