Lambda Expressions

Introduction

In the earlier post, we talk about anonymous methods, we had seen that by using anonymous methods, we can define a method without providing a name to the method, in addition to it, we were also not required to specify the access specifier and the return type of the method. Lambda expressions are a further shortcut to writing anonymous methods.

To understand more let’s take an easy example, a program to add two numbers using the anonymous method

using System;

namespace LambdaExpressions
{
    public delegate int AddDelegate(int i, int j);

    class Program
    {
        static void Main()
        {
            AddDelegate dd = delegate (int ii, int jj)
            {
                return ii + jj;
            };

            int result = dd.Invoke(10, 5);
            Console.WriteLine(result);
            Console.ReadLine();
        }
    }
}

So, there was no need of giving the access specifier and the return type for the method if we write an anonymous method. But we are still required to write the keyword “delegate” and the parameter type while implementing an anonymous method. So, to do away with this, lambda expressions were introduced, using which, there was no need to specify the “delegate” keyword and the parameter type. Hence, the below-mentioned code:

AddDelegate dd = delegate (int ii, int jj)
{
    return ii + jj;
};

Could be rewritten using lambda expression as follows:

AddDelegate dd = (int ii, int jj) => ii + jj;

Notice the operator “=>” we have used, this is called the “lambda operator”. Now we can do away with specifying the “delegate” keyword and the type of the parameter. But can we specify the parameter type? Yes, you can, but there is no need. So, if you specify the parameter type, the program will still run, look at the below-mentioned code:

Code for Program class:

using System;

namespace LambdaExpressions
{
    public delegate int AddDelegate(int i, int j);

    class Program
    {
        static void Main()
        {
            AddDelegate dd = (int ii, int jj) => ii + jj;
            int str = dd.Invoke(10, 5);
            Console.WriteLine(str);
            Console.ReadLine();
        }
    }
}

The lambda operator => divides a lambda expression into two parts. The left side is the input parameter and the right side is the lambda body.
So, a lambda expression takes one of the two forms:

  1. Single Line Expression – (input-parameters) => expression; – also known as “expression lambda”
  2. Multiple lines expression – (input-parameters) => { //some statements }; – also known as “statement lambda”

We have seen the example of the first, which is a shortcut to use the anonymous method, i.e. lambda having an expression as its body. Now we will look at the second form, in which a lambda having a statement block as its body.

Consider the following program:

using System;

namespace LambdaExpressions
{
    public delegate double AddDelegate(int x, int y);
    class Program
    {
        static void Main()
        {
            AddDelegate cd = delegate (int x, int y)
            {
                var total = x + y;
                var discount= IsEligibleForDiscount(total);
                if (!discount)
                    return total;
                return total - total * 0.5 / 100;
            };
            double b = cd.Invoke(10, 20);
            Console.WriteLine(b);
            Console.ReadLine();
        }


        static bool IsEligibleForDiscount(int total)
        {
            return total > 100;
        }
    }
}

In this program, there is a delegate “AddDelegate” which returns a “double” value and has two parameters of “int” type. Then we implemented an anonymous method which returned a total of these two number based on some logic. Now, when we called the delegate by the following line

double b = cd.Invoke(10, 20);

Now, we will implement this with the help of a lambda expression. We can simply replace the following code:


AddDelegate cd = delegate (int x, int y)
{
    var total = x + y;
    var discount= IsEligibleForDiscount(total);
    if (!discount)
        return total;
    return total - total * 0.5 / 100;
};

with


AddDelegate cd = (x, y) =>
{
    var total = x + y;
    var discount = IsEligibleForDiscount(total);
    if (!discount)
        return total;
    return total - total * 0.5 / 100;
};

So, the complete program will be as follows:


using System;

namespace LambdaExpressions
{
    public delegate double AddDelegate(int x, int y);
    class Program
    {
        static void Main()
        {
            AddDelegate cd = (x, y) =>
            {
                var total = x + y;
                var discount = IsEligibleForDiscount(total);
                if (!discount)
                    return total;
                return total - total * 0.5 / 100;
            };

            var b = cd.Invoke(10, 20);
            Console.WriteLine(b);
            Console.ReadLine();
        }


        static bool IsEligibleForDiscount(int total)
        {
            return total > 100;
        }
    }
}

Lambda expression with Generic Delegates

As we know generic delegate allow us to invoke delegate instance without diffing the delegate,
A Lambda expression fits sweetly with Generic delegates.

Lambda expression with Func

We know that a Func is one of generic delegate and we can attach an anonymous function to it. Since a lambda expression is nothing but a function, we can attach it with the Func. In the following example, we will attach a lambda expression with fun anonymous delegates.


using System;

namespace LambdaExpressions
{
    class Program
    {
        static void Main()
        {
            Func<int, int, int> fun = (x, y) => x + y;
            Console.WriteLine(fun(10, 10));
            Console.ReadLine();
        }
    }
}

Lambda expression with Action

As explained above we can also use lambda expression with Action delegate, Below is the example for the same.

using System;

namespace LambdaExpressions
{
    class Program
    {
        static void Main()
        {
            Action<string> fun = (str) => Console.WriteLine($"Welcome {str}");
            fun("Mahesh");
            Console.ReadLine();
        }
    }
}

similler way we can use lambda expression with Predicate.

Lambda expression with collection

Lambda expression work very well with collection, It’s very handy to sort and/or shuffle a collection using a lambda expression. Here are a few examples.


using System.Linq;

namespace LambdaExpressions
{
    class Program
    {
        static void Main()
        {
            int[] data = { 1, 2, 4, 5, 6, 10 };
            int[] even = data.Where(fn => fn % 2 == 0).ToArray();
            int[] odd = data.Where(fn => fn % 2 != 0).ToArray();
        }
    }
}


You can test your knowledge by free online lambda expression quiz, also here is the collection of the Lambda expression Interview Question.

Leave a Reply

Your email address will not be published. Required fields are marked *