.Net application development specialists
asp.net, c#, vb.net, html, javascript, jquery, html, xhtml, css, oop, design patterns, sql server, mvc and much more
contact: admin@paxium.co.uk

Paxium is the company owned by myself, Dave Amour and used for providing IT contract development services including


  • Application development - Desktop, Web, Services - with Classic ASP, Asp.net WebForms, Asp.net MVC, Asp.net Core
  • Html, Css, JavaScript, jQuery, React, C#, SQL Server, Ado.net, Entity Framework, NHibernate, TDD, WebApi, GIT, IIS
  • Database schema design, implementation & ETL activities
  • Website design and hosting including email hosting
  • Training - typically one to one sessions
  • Reverse Engineering and documentation of undocumented systems
  • Code Reviews
  • Performance Tuning
  • Located in Cannock, Staffordshire
Rugeley Chess Club Buying Butler Cuckooland Katmaid Pet Sitting Services Roland Garros 60 60 Golf cement Technical Conformity Goofy MaggieBears Vacc Track Find Your Smart Phone eBate Taylors Poultry Services Lafarge Rebates System Codemasters Grid Game eBate DOFF

Lambda expressions in C#

Ok so what is a lamda expression?

Good question and in fact what is a lambda?  Well lambda is the 11th letter of the greek alphabet and was also used to give a name to an area of mathematics called lambda calculus.  Lambda calculus is a formal system for function definition, function application and recursion.  Now at the moment this won't mean much but by the time you have read this article it will all make sense particularly the part about function defintion.

Lambda expressions are not an invention of .net - they already exist in other languages such as Lisp and Python.

So to explain what a Lamda expression is I am going to start off by giving a very short definition and then walk you through some code,  We shall start off with some code and then make it better one step at a time such that it evolves and eventually it shall end up using lamda expressions when hopefully all shall become clear.

I would highly recomend that you follow this process yourself by getting the code up and running rather than just reading the article.

Ok so we are going to create a C# console application using Visual Studio 2008.

The initial code will create a string array of uk counties and then call a method which just outputs them to the console.  We won't include all of the counties in the array so apologies if your county is missed out!

So the first version of our code is pretty straightforward and looks like this: 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace LambdaExpressions
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] counties = new string[]
            {
                "Derbyshire", "Staffordshire", "Sussex", "Kent", "Yorkshire",
                "Nottinghamshire", "Avon", "Cheshire", "Rutland"
            };
 
            DisplayCounties(counties);
 
            Console.Read();
        }
 
        static void DisplayCounties (string[] counties)
        {
            foreach (string c in counties)
            {
                Console.WriteLine(c);
            }
        }
    }
}


And so if you run this code it will of course output all of the counties to the console. 

Now lets say we want to output counties to the screen but only for those which are shires - ie they end in shire.  We could do this by writing a method which does just that and then our code would look like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace LambdaExpressions
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] counties = new string[]
            {
                "Derbyshire", "Staffordshire", "Sussex", "Kent", "Yorkshire",
                "Nottinghamshire", "Avon", "Cheshire", "Rutland"
            };
 
            DisplayShireCounties(counties);
 
            Console.Read();
        }
 
        static void DisplayCounties (string[] counties)
        {
            foreach (string c in counties)
            {
                Console.WriteLine(c);
            }
        }
 
        static void DisplayShireCounties(string[] counties)
        {
            foreach (string c in counties)
            {
                if (c.ToUpper().EndsWith("SHIRE"))
                {
                    Console.WriteLine(c);
                }
            }
        }
    }
}


Now supposed we wanted to extend this idea and display counties according to some other criteria too.  Lets say we want counties which are not shires and counties with less than 7 characters.  We could code more methods like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace LambdaExpressions
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] counties = new string[]
            {
                "Derbyshire", "Staffordshire", "Sussex", "Kent", "Yorkshire",
                "Nottinghamshire", "Avon", "Cheshire", "Rutland"
            };
                                   
            DisplayShireCounties(counties);
 
            Console.WriteLine("---------------------------------");
 
            DisplayNonShireCounties(counties);
 
            Console.WriteLine("---------------------------------");
 
            DisplayCountiesWithLessThanSevenCharacters(counties);
 
            Console.Read();
        }
 
        static void DisplayCounties (string[] counties)
        {
            foreach (string c in counties)
            {
                Console.WriteLine(c);
            }
        }
 
        static void DisplayShireCounties(string[] counties)
        {
            foreach (string c in counties)
            {
                if (c.ToUpper().EndsWith("SHIRE"))
                {
                    Console.WriteLine(c);
                }
            }
        }
 
        static void DisplayNonShireCounties(string[] counties)
        {
            foreach (string c in counties)
            {
                if (!c.ToUpper().EndsWith("SHIRE"))
                {
                    Console.WriteLine(c);
                }
            }
        }
 
        static void DisplayCountiesWithLessThanSevenCharacters(string[] counties)
        {
            foreach (string c in counties)
            {
                if (c.Length < 7)
                {
                    Console.WriteLine(c);
                }
            }
        }
    }
}
 


And so if we wanted another dozen methods to do different selections or filters then we could just carry on writing more methods.  There is a better and more flexible way of doing this though and that is to use delegates.  If you are not sure what delegates are then you need to get your head round that first before continuing with this article and you can do so here:

http://www.audacs.co.uk/ViewPage.aspx?PageID=474

The code below shows this rewritten to use delegates.  Note that this is better not just because you probably end up writing smaller and less verbose code but also because it is more felxible and easy to extend.

So the new code looks like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace LambdaExpressions
{
    delegate bool PerformActionOnString (string s);
   
    class Program
    {
        static void Main(string[] args)
        {
            string[] counties = new string[]
            {
                "Derbyshire", "Staffordshire", "Sussex", "Kent", "Yorkshire",
                "Nottinghamshire", "Avon", "Cheshire", "Rutland"
            };
 
            DisplayCounties(counties, new PerformActionOnString(IsShireCounty));
            DisplayCounties(counties, new PerformActionOnString(IsNotShireCounty));
            DisplayCounties(counties, new PerformActionOnString(LessThanSevenCharacters));
 
            Console.Read();
        }
 
        static void DisplayCounties (string[] counties, PerformActionOnString method)
        {
            foreach (string c in counties)
            {
                if (method(c))
                {
                    Console.WriteLine(c);
                }
            }
        }
 
        static bool IsShireCounty(string county)
        {
            return county.ToUpper().EndsWith("SHIRE");
        }
 
        static bool IsNotShireCounty(string county)
        {
            return !county.ToUpper().EndsWith("SHIRE");
        }
 
        static bool LessThanSevenCharacters(string county)
        {
            return county.Length < 7;
        }
    }
}
 


So we have got rid of all the different methods which outputted counties to the screen and replaced these with just one method called  DisplayCounties.  This method takes a string array as a parameter and also now takes a delegate instance as well.  The delegate instance is of the type of PerformActionOnString which is a delegate signature we have declared at the top of the code.  Any instance of the delegate must accept a single string as an argument and return a bool.  Within our DisplayCounties method we then invoke the method this delegate refers to on each string in the array and if the boolean result is true we output the county to the console.

This enables us to now write simple, smaller methods which do a comparison on one string and we then pass that into our DisplayCounties method via a delegate.

So the client part of our code now looks like this: 

       DisplayCounties(counties, new PerformActionOnString(IsShireCounty));
       DisplayCounties(counties, new PerformActionOnString(IsNotShireCounty));
       DisplayCounties(counties, new PerformActionOnString(LessThanSevenCharacters));


And so now if we wanted a new method  - lets say counties with an X in we would write our new comparison method like this:

        static bool ContainsX(string county)
        {
            return county.ToUpper().Contains("X");
        }


And then our client code would just have one extra line as follows:

          DisplayCounties(counties, new PerformActionOnString(ContainsX));


Now if we wanted to simplify and compact our code even further we could do away with all of our comparison methods and use inline anonymous methods instead.

If you are not sure what an anonymous method is, it is when we put the code for a method inline rather than putting a method name.  So our new code would end up looking like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace LambdaExpressions
{
    delegate bool PerformActionOnString (string s);
   
    class Program
    {
        static void Main(string[] args)
        {
            string[] counties = new string[]
            {
                "Derbyshire", "Staffordshire", "Sussex", "Kent", "Yorkshire",
                "Nottinghamshire", "Avon", "Cheshire", "Rutland"
            };
 
            DisplayCounties(counties, delegate(string county) { return county.ToUpper().EndsWith("SHIRE"); });
            DisplayCounties(counties, delegate(string county) { return !county.ToUpper().EndsWith("SHIRE"); });
            DisplayCounties(counties, delegate(string county) { return county.Length < 7; });
            DisplayCounties(counties, delegate(string county) { return county.ToUpper().Contains("X"); });
 
            Console.Read();
        }
 
        static void DisplayCounties (string[] counties, PerformActionOnString method)
        {
            foreach (string c in counties)
            {
                if (method(c))
                {
                    Console.WriteLine(c);
                }
            }
 
            Console.WriteLine("-----------------------------");
        }
    }
}
 


So in the highlighted yellow section we have put the entire method body but put the word delegate rather than a method name.  So this method is inline and is anonymous as it doesn't have a name.  This leads to very compact code and is often a better way to when this is the only part of your program you will use that method.  The end result is exactly the same as the previous code but now the method is inline and anonymous.  This now makes our code very easy to extend and you can do so with just one line of code!

Ok so now we get to the point of the article - Lamda expressions.  The above way of using inline anonymous methods is very wideley used and so to make our lives easier, Microsoft gave C# the ability to use lamda expressions.  A lamda expression is a shorthand or easier way of defining anonymous methods.

Lets take a look at out last piece of code but written with lamda expressions instead.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace LambdaExpressions
{
    delegate bool PerformActionOnString (string s);
   
    class Program
    {
        static void Main(string[] args)
        {
            string[] counties = new string[]
            {
                "Derbyshire", "Staffordshire", "Sussex", "Kent", "Yorkshire",
                "Nottinghamshire", "Avon", "Cheshire", "Rutland"
            };
 
            DisplayCounties(counties, c => c.ToUpper().EndsWith("SHIRE"));
            DisplayCounties(counties, c => !c.ToUpper().EndsWith("SHIRE"));
            DisplayCounties(counties, c => c.Length < 7);
            DisplayCounties(counties, c => c.ToUpper().Contains("X"));
 
            Console.Read();
        }
 
        static void DisplayCounties (string[] counties, PerformActionOnString method)
        {
            foreach (string c in counties)
            {
                if (method(c))
                {
                    Console.WriteLine(c);
                }
            }
 
            Console.WriteLine("-----------------------------");
        }
    }
}


So our old code looked like this:

DisplayCounties(counties, delegate(string county) { return county.ToUpper().EndsWith("SHIRE"); });


And now this looks like this:

DisplayCounties(counties, c => c.ToUpper().EndsWith("SHIRE"));


So when the lamda expression is compiled, the compiler will produce the same thing as the old delegate code - the lamda expression is just a shorter, easier to use facade for us humans who like things to be compact and simple. 

You can think of the c replacing delegate(string county)  - The compiler can do this as it knows it is a lamda expression because of the => operator and it knows that the delegate arguments is just 1 string as it knows what kind of delegate the DisplayCounties method expects.  The code to the right of the => operator is the main code which would be the delegate method.  This should evaluate to the type the delegate should return.  So the compiler knows that DisplayCounties expects a delegate as it's second argument and that delegate is of type PerformActionOnString which returns a bool.  Therefore the piece of code on the right of our => must evaluate to a bool.

So when to use a lamda expression?  Well anytime you have an anonymous method inline then you can use a lamda expression.

If you wanted to, in our above code you could even do this kind of thing:

PerformActionOnString m = c => c.ToUpper().EndsWith("SHIRE");
 
DisplayCounties(counties, m);

They are also used an awful lot in Linq.  This is becuase many of the methods in Linq do some kind of filtering or selection and so just as in our example you can pass in a lamda expression to act as your filter logic.

So thats about it for now. Any comments are welcome via the form below.