C#1 to C#7.2 – Delegates and Lambdas

This article is about looking at a specific C# feature and see how the functionality has been changed as each new C# version is released.

It’s nice to look at “What’s New” articles but sometimes I find myself unable to remember at which version a specific feature can be used.

What are they?

A delegate is a type that represents references to methods with a particular parameter list and return type. In C++ land they refer to them as function pointers. Let’s see how they have evolved into anonymous delegates and then rebranded as Lambdas.

For the basis of comparison I am going to use an Add method that takes two numeric values and returns the sum. The example below is not using a delegate.


  • We declare a delegate myDele which takes two integer parameters and returns an int.
  • We declare an Add method with the same signature.
  • A delegate is a type so we have to instantiate it with our Add method.
  • We can then call our delegate in exactly the same way as we would call our method directly.


  • Microsoft saw that everyone was creating similar delegate types and so decided to add some common ones directly in the framework with varying number of parameters.
  • Func delegates take zero or more inputs and always returned a value.
  • Action delegates take zero or more inputs and does not return a value.
  • Predicate delegates take zero or more inputs and return a Boolean value.

C# 2.0 introduced Anonymous Methods

  • Naming stuff is hard. Having to name a method just so we can call it from a delegate made naming for the sake of naming.
  • Here we embed the code at the time we declare the delegate.
  • This is downside to this method. We need to declare the input types twice.


C# 3.0 introduced the Lambda Expression syntax. This is not a new feature because under the covers they are still Anonymous Methods that map to delegates. It is syntactic sugar for us and the compiler will still generate the same MSIL code.

A lambda expression takes the format =>

  • Notice that we need to write less boilerplate code to do the same thing.
  • The Add method is still summing two numbers but the compiler is now creating and naming our method under the covers.

  • If the expression is only a single line of code, we can exclude the braces and return keyword.

  • The code is getting smaller. If the function takes zero parameters we can replace them with ()

CS4 – CS7.2

Nothing changed.

Usage Examples

We have a List and we want to sort the list by FirstName. List has a Sort method with the following signature:

List.Sort Method (Comparison)

Where Comparison is a public delegate int Comparison(T x, T y)

We need a function that will do a type comparison (in out example STRING comparison) and return one of three int values

  • Less than 0 = x is less than y
  • Equals 0 = x is equal to y
  • Greater than 0 = x is greater y

For string types they have a int CompareTo(Object obj) method that returns the same INT values as the Sort method needs.


In the demo code here there are other real world examples.