DEV Community

Ravi Sankar Rao
Ravi Sankar Rao

Posted on

C# Delegates Simplified — Part 3

This article is the third one from a series of 3 articles on C# delegates. If you are new to delegates and haven’t gone through the previous ones, I suggest you to go through them first

We all might have read articles that say “If you are using lambda expressions in C#, you are already working with delegates” but they don’t discuss anything about how they are closely related.

In this article we will discuss the journey from delegate to lambda expressions.

Below we have a person class with two properties.

public class Person
{
        public string FirstName { get; set; }
        public string LastName { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

We have a function somewhere outside this class which takes a Person parameter and returns formatted name

public string GetFullName(Person person)
{
       return $"{person.FirstName} {person.LastName}";
}
Enter fullscreen mode Exit fullscreen mode

Lets declare a delegate for the function which should match the signature.

public delegate string PersonFormatter(Person person);
Enter fullscreen mode Exit fullscreen mode

Using above delegate with our function will be like this

var person = new Person { FirstName = "John", LastName = "Doe" };

PersonFormatter formatter = GetFullName;
var fullName = formatter(person);
Enter fullscreen mode Exit fullscreen mode

Here we have a separate function for our delegate, but for most of our day-to-day programming we don’t need to write a separate function for our delegate to be used.

We can achieve use a delegate by using something known as Anonymous functions in C#. Below is how we can do that.

PersonFormatter formatter = delegate (Person person)
{
       return $"{person.FirstName} {person.LastName}";
};

// No changes in the way delegate is invoked
var fullName = formatter(person);
Enter fullscreen mode Exit fullscreen mode

The syntax has 4 major parts

  • a variable named formatter of type PersonFormatter

  • use of delegate keyword

  • Person variable in round brackets

  • a function body that does the same as our GetFullName function earlier. This function body does not has a name, hence an Anonymous function.

We can simplify the use of anonymous function while we initialize our delegate. We can get rid of the ‘delegate’ keyword and use ‘=>’ which is commonly knows as ‘goes to’ operator or famously in our case as the ‘lambda’ operator.

PersonFormatter formatter = (Person person) =>
{
        return $"{person.FirstName} {person.LastName}";
};
Enter fullscreen mode Exit fullscreen mode

We removed the delegate keyword, and added a lambda operator after our Person variable.

We can simplify this even more. Taking advantage of C#’s Type Inference, we can also get rid of the Person type and just use a parameter name as shown below.

PersonFormatter formatter = (person) =>
{
        return $"{person.FirstName} {person.LastName}";
};
Enter fullscreen mode Exit fullscreen mode

We got rid of the type Person, and are just using person as a parameter . C#’s Type inference automatically kicks in due to the delegate type PersonFormatter that the parameter it needs is of Person type.

Interesting till now ? More on the way.

We can simplify this even further. It happens, if we are working with single parameter delegates, we don’t even need the brackets around the parameter as well.

PersonFormatter formatter = person =>
{
        return $"{person.FirstName} {person.LastName}";
};
Enter fullscreen mode Exit fullscreen mode

Below, I have renamed person to ‘p’ for simplification.

PersonFormatter formatter = p =>
{
        return $"{p.FirstName} {p.LastName}";
};
Enter fullscreen mode Exit fullscreen mode

This is what we call as “Statement Lambdas”, meaning expressions are enclosed in braces.

We can simplify this even further. If our anonymous function body has only one statement, we can get rid of curly brackets and the return keyword as well.

PersonFormatter formatter = p => $"{p.FirstName}{p.LastName}";
Enter fullscreen mode Exit fullscreen mode

This is called as “Expression Lambdas

If we are working with more that one parameters, we have to use brackets around our parameter

public delegate int DoSomeMath(int a, int b);

// Below is to add two numbers
DoSomeMath someMath = (a, b) => a + b;
Enter fullscreen mode Exit fullscreen mode

Hope the articles helped to bridge the gap between delegates and lambda expressions.

Top comments (0)