Lambda Expressions and Anonymous Methods in C#

usmanmalik's Avatar author of Lambda Expressions and Anonymous Methods in C#
This is an article on Lambda Expressions and Anonymous Methods in C# in C#.
A lambda expression is basically an unnamed method which is used in place of delegate instance. Lambda expressions are also some times called inline delegates and they are mostly used with delegates. Anonymous methods can be represented in a more concise way using these lambda expressions. Lambda expressions basically provide a different syntax to write and invoke the functionality that is achieved through normal methods in C#. Anonymous methods and lambda expressions, both provide a way to write functions inline; but they are implemented in slightly different manners with lambda expressions being little easier. Lambda expressions make use of the type inference feature which was introduced in C# 3.0. Compiler makes use of type inference feature to compile the variable on the basis of context in which it is being used. In this article, we are going to explain both of these concepts, the lambda expressions and anonymous methods. We will take addition method as example and will perform addition through lambda expressions and anonymous methods. We will also explain the similarities and differences between the lambda expressions and the anonymous methods and will explain how to use them.

Lambda Expressions



Before dwelling straight into code samples, let us first explain itty bitty of lambda expressions. Basically, lambda expressions have two parts: Parameters that are passed to the lambda expressions and secondly the execution code. The parameter and the execution code are separated by a special symbol called =>. So a lambda expression looks like

(Parameter) => Execution code

In case you have only one parameter in a lambda expression, you can omit the bracket. Lambda expressions are written in place of delegate instance but at run time the compiler converts the lambda expression to a delegate instance or Expression<TDelegate>, which is an expression tree.

Now, enough of theoretical elaborations, we will switch straight to the code to see how lambda expressions work. Have a look at Example1.

In Example1, we will explain that how you can achieve functionality with delegates instance without using lambda expressions. In Example1, we will perform sum of two numbers through conventional delegate instance. In Example2, we will use lambda expressions to achieve the similar functionality. Look at Example1 first.

Example1 (Addition through delegate instances)

Code:
namespace CSharpTutorial
{
    class Math
    {
        public int sum(int x, int y)
        {
            return x + y;
        }
    }
    class Program
    {
        delegate int del(int x, int y);

        static void Main(string[] args)
        {
            Math m = new Math();
            del add = m.sum;

            int result = add(5, 10);
            Console.WriteLine(result);

            Console.ReadLine();
        }
    }
}
In Example1, we have a class named Math which contains only one method sum. The method sum has a return type of integer and it has two arguments of type integer. Next, inside the class Program, we have defined a delegate named del, which has a return type of int and can take two parameter of type integer. The instance of this delegate can store any method which matches the signature of the delegate. Fortunately we have method sum of class Math that matches the signature of the delegate del. Therefore, we have declared an instance of delegate del named add which points to the sum method of class Math. Next, we passed two parameters of type integer to that delegate instance and stored the result in the integer type variable called result. We then displayed the value on the output console. The output of the Example1 will be the additions of the variables that we passed to the delegate instance add which are 5 and 10. The result would be 15 and is shown in the output console window as follows.



Now, In Example1, we achieve the desired functionality through a delegate instance; without using any lambda expression. In Example2, we will show you how lambda expressions can be used to do what we have done in Example1. Have a look at Example2.

Example2 (Addition through lambda expressions)
Code:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CSharpTutorial
{
    class Program
    {
        delegate int del(int x, int y);

        static void Main(string[] args)
        {    
            del add = (x, y) => x + y;

            int result = add(5, 10);
            Console.WriteLine(result);

            Console.ReadLine();
        }
    }
}
In Example2, we have totally removed the Math class and there is no sum method. We said earlier that lambda expressions provide an abridged way to write methods. Therefore, instead of storing a method pointer in delegate instance add we write lambda expression. Consider the following line of code.

del add = (x, y) => x + y;

Here in the delegate instance add, we referred to method sum in Example1, but in this case we are storing a lambda expression (x, y) => x + y;

Here, x and y are the parameters, followed by =>. And x +y is the execution code which means that this lambda express can take two variables and then can return sum of these variables.

Behind the scene what happens is that compiler actually writes a private method for every lambda expression and moves the parameters and execution code to that method and executes that method but all those complexities are hidden from the end user.

Notice the code again, actually the parameters of the lambda expressions correspond to the parameter of the delegate and the return type of the lambda expression corresponds to the return type of the delegate. Here in Example1, the execution code x + y will return integer which is similar to the integer return type of delegate del. The output of Example2 will be exactly similar to that of Example1.

You must be wondering that we didnít specify the type of the parameter inside the lambda expression. We simply wrote (x, y) in the parameter portion of the lambda expressions instead of writing full (int x, int y). Actually, compiler automatically assigns the type to the parameter based on the context in which they are used. In Example1, the compiler will check the type of the delegate instance in which we are returning the values from lambda expressions therefore it will automatically assign the type based in the delegate being used. The delegate parameters had type integer, therefore compiler will assign the type integer to the lambda expressions parameter as well. However, you can explicitly specify the type of the parameter using statements like (int x, int y).

Another important thing to note here is that apart from writing execution code in the form of expressions, you can also write execution code in the form of code blocks. For Example you can also write the lambda expression

(x, y) => x + y;

as

(x, y) => {return x + y;};

Till now, we have only added two variables inside the lambda expressions. Apart from performing arithmetic functions using lambda expressions, we can do virtually anything inside the execution code of the lambda expression. For instance we can also perform comparison inside the body of the execution code. Consider next code snippet for that purpose. We have not numbered it Example3, because this is actually extension of the Example2 in lambda expressions section. In this code section, we would actually compare the two values. Consider the following code snippet.

Comparison Using Lambda Expressions
Code:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CSharpTutorial
{
    class Program
    {
        static void Main(string[] args)
        {
            List<int> integers = new List<int> { 2, 3, 1, 8, 4, 13, 41, 5, 48 };
            var evennums = integers.FindAll(k => k % 2 == 0);
            var evennums2 = integers.FindAll((int k) => { return k % 2 == 0; });

            foreach (int num in evennums)
            {

                Console.Write(num+", ");
            }
            Console.WriteLine();
            foreach (int num in evennums2)
            {

                Console.Write(num+", ");
            }
            Console.ReadLine();
        }
    }
}
Now have a look at the above code snippet, we have collection of integer type named integer and we have stored some integer type constants in this list. Consider the following line

var evennums = integers.FindAll(k => k % 2 == 0);

Here we have called FindAll method on integer and inside the method we have written lambda expression, k => k % 2 == 0. This expression means that I am passing you a variable k, check if this variable is fully divisible by 0, if it is divisible by zero return it to me. This is in the form of expression. Next we have written the same lambda expression in the form of code block as follows

var evennums2 = integers.FindAll((int k) => { return k % 2 == 0;};

Here we have again said the lambda expression that returns all the numbers from the list of integer collection that are divisible by 2 or in other words are odd. The output this code snippet will be all the even numbers from the integer collection displayed twice one from the expression and one from the code blocks.

Output



Anonymous Methods



Anonymous methods are basically C # 2.0 versions of lambda expressions. With the advent the advent of C# 3.0, anonymous methods have been subsumed by lambda expressions. Anonymous methods are pretty similar in nature to lambda expressions with following three major differences.
  • Unlike lambda expressions, there are no implicitly typed parameters in anonymous methods.
  • In lambda expressions, we could write execution code in the form of both expressions and code blocks. On the other hand you cannot write execution code anonymous methods in the form of expressions; you have to write it in the form of code blocks in case of anonymous methods.
  • In anonymous method you cannot compile code to expression tree by assigning it to Expression<T> which was the case with lambda expressions.
Remember, in lambda expression section, we performed addition using lambda expression. Now we are going to perform addition using anonymous method. You will see in Example3 that how lambda expressions differ from anonymous methods.

Simply put, anonymous methods are similar to lambda expressions in syntax with two differences.
  • You will have to prefix the word delegate before anonymous method.
  • There is no => expression in anonymous method unlike lambda expressions.
Without wasting any further time, we will straight jump to Example3 so pay attention.

Example3 (Addition through anonymous methods)
Code:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CSharpTutorial
{
    class Program
    {
        delegate int del(int x, int y);
        static void Main(string[] args)
        {
    
            del add = delegate (int x, int y) {return x + y;};

            int result = add(5, 10);
            Console.WriteLine(result);

            Console.ReadLine();
        }
    }
}
Closely look at the code in Exampl3, you will find very little difference between the code in Exampl2 and Example3. This actually signifies the similarity between lambda expressions and the anonymous methods. Code might look similar but fact of the matter is, Example2 employed lambda expression for addition purposes where as in Example3 we used anonymous. The only differing lines in the code of both examples is the following one

del add = delegate (int x, int y) {return x + y;};

Focus on the code on the right side of equals sign. As aforementioned, we begin anonymous methods with keyword delegate; therefore we append it at the start of the method. Next we specified the parameters that an anonymous method will accept, along with the type of the parameter. Remember, you did not have to specify the type in case of lambda expressions but you will have to specify it in case of anonymous method otherwise code will not compile. The last thing is the code block which returns the sum of x and y. You could simply write it in the form of x + y in case of lambda expressions but here you will have to specify this in terms of a code block {return x+y ; };.

The output of Example1, Example2 and Example2 would be identical since we are achieving same functionality through a delegate instance method, a lambda expression and anonymous method.

In this article we explained two of the advanced C# concepts, the lambda expressions and the anonymous methods. We explained how we can achieve desired functionality using both of these methods. We also explained differences between the two and how they are used. I would recommend you to further explore the lambda expressions and anonymous methods and in case if you have any queries, you can leave the reply and I will follow back a.s.a.p.
shabbir like this