Delegate, Anonymous Method and Lamda Expression in C# (Part 1/2)



Hello everyone, in this blog I will discuss Lamda Expression which is an important part of C# programming language. It is extensively used in LINQ, delegates and events. Before I discuss what Lamda expression is, I will first briefly discuss delegates and anonymous function because it is a kind of prerequisite for understanding Lamda Expression.

What is a Delegate?
In simple words, delegate holds a reference to a method or function. Once we have a reference to a method then we can call that method or function by that reference. That’s it.

Why Delegate?

  1. Delegates support events and a solid pillar for event handling mechanism
  2. Delegates execute methods at runtime without having their information about its definition at compile time

How to create a Delegate?
Just like the way we create an instance of a class i.e. first we define a class which describes an object and create an instance of it. Similarly, we first define how a delegate would look like and then create an instance of it. By how a delegate look like, I mean what would be its return type and input parameters (method signature).
Thus, a delegate will hold the reference to the method that has the same return type and method signature as mentioned by that delegate. Below is the declaration of a delegate.
    using System;
    delegate void JustPrint();

Delegate declared has a name “JustPrint” just like any class name “Person” and it will hold reference to methods whose return type is void and that do not take any parameter.
Now let’s create a method that agrees with the delegate definition.
    using System;
    delegate void JustPrint();
    class Demo
    {
        public static void MyMethod()
        {
            Console.WriteLine(“Soon I will be called via a delegate :-D ”);
        }
    }

Awesome. Now I have created a method “MyMethod” that can agree with the return type and parameters of our delegate “JustPrint”. Time to create instance of delegate, like the way we create an instance of the class. Let’s create main function and inside of it instantiate our JustPrint delegate.

    delegate void JustPrint();
    class Demo
    {
        public static void MyMethod()
        {
            Console.WriteLine(“Soon I will be called via a delegate :-D ”);
        }
        public static void Main(string[] args)
        {
            JustPrint print = Demo.MyMethod;
            // Or JustPrint print  = new JustPrint(Demo.MyMethod);
            print();    // Calling MyThod with delegate instance
            Console.ReadKey();
        }
    }
OUTPUT:
Soon I will be called via a delegate :-D
First thing to note is how we gave the reference of MyMethod function (static method of Demo class) to our JustPrint delegate’s instance print. We did not place parenthesis after MyMethod. This is how we give the reference of method to a delegate’s instance so that it can call the method. Frankly, it is obvious that if we place parenthesis after method name then it will call the method (rather than giving its reference) that is why parenthesis are not used.

Delegate for Method with return type and input parameter
While this was the world’s simplest and easiest example about delegate, let’s see what happens if we have a method with a return type and a parameter. I will create a method that takes money and return double of it. For that, my delegate obviously must declare same return type and method signature. But this time, let’s make the method an instance method of the class rather than a static method. See code below.

 delegate decimal CalculateMoney(decimal m);
    class Demo
    {
        public decimal DoubleMoney(decimal money)
        {
            return 2 * money;
        }
        public static void Main(string[] args)
        {
            // First create instance of class so that we can give its reference to delegate
            // as we know instance methods of a class can only be called via their class’s object
            Demo d = new Demo();

            //Giving reference of method to DoubleMoney method to instance of CalculateMoney delegate
            CalculateMoney calculate = d.DoubleMoney;

            //Calling DoubleMoney via calculate
            decimal money = calculate(1000);
            Console.WriteLine("Doubled Money:" +money);
            Console.ReadKey();
        }
    }
OUTPUT:
2000
As you can see, there is not much of the difference between assigning a method’s reference to delegate instance that doesn’t return anything nor takes any argument and the method that takes arguments and returns something. We only give it parameter when calling the method and store value returned by the method being called via delegate instance.


Multicasting
The best part of delegates is that they support multicasting which means you can chain methods together with a delegate instance so that when you call an instance of delegate it calls all the methods chained to it. Normally, such method doesn’t have a return type if they do then the value is returned by last method in the chain.  
To add methods to an instance of delegate use += operator and -= to remove a method from chain.
The example below creates a delegates “LIfe” that can hold reference to a method whose return type is void and takes an object of Person class. In Person class I have overridden the ToString method of object class to define a string representation of Person class . In main class, I created instance of Life and assign Born  method to it and chaied all other methods to it.

Finally, it can be observed that only one call to Life instance passed the person object to all the chained method and they are called in order they are added into the chain.

     delegate void Life(Person p);
    public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public override string ToString()
        {
            return FirstName + " " +LastName;
        }
    }
    public class Human
    {
        public static void Main(string[] args)
        {
            // First create instance of person class so that it can be passed to all chained methods
            Person man = new Person() { FirstName = "Leonardo", LastName = "DiCaprio" };
            // as we know instance methods of a class can only be called via their class’s object
            Life person = Human.Born ;
            person += Human.WentToSchool;
            person += Human.SingingDancing;
            person += Human.StartedActing;
            person += Human.WonOscar;

            person(man); Console.WriteLine();
            person -= Human.WentToSchool;
            person(man);


            Console.ReadKey();
        }
        public static void Born(Person person)
        {
            Console.WriteLine(person + " is born");
        }
        public static void WentToSchool(Person person)
        {
            Console.WriteLine(person + " went to school");
                ;
        }
        public static void SingingDancing(Person person)
        {
            Console.WriteLine( person + " is singing and dancing");
        }

        public static void StartedActing(Person person)
        {
            Console.WriteLine(person + " started working as an actor in hollywood");
        }
        public static void WonOscar(Person person)
        {
            Console.WriteLine(person + " won Oscar");
        }


    }
OUTPUT:
Leonardo DiCaprio is born
Leonardo DiCaprio went to school
Leonardo DiCaprio is singing and dancing
Leonardo DiCaprio started working as an actor in hollywood
Leonardo DiCaprio won Oscar

Leonardo DiCaprio is born
Leonardo DiCaprio is singing and dancing
Leonardo DiCaprio started working as an actor in hollywood
Leonardo DiCaprio won Oscar

I will discuss anonymous function and lamda expression in the next blog. zzzzzzzzzzzzzz


Comments

  1. Casino City Hotel, Atlantic City - DrmCD
    Enjoy modern 거제 출장마사지 amenities and 이천 출장안마 fantastic casino gaming 광양 출장마사지 at the Casino City Hotel, a perfect place to stay in 구미 출장샵 Atlantic City. Dr.Mcd 익산 출장샵 recommends guests staying at Atlantic

    ReplyDelete

Post a Comment

Popular posts from this blog

Implementing Basic and JWT Token authentication with C# .NET

.NET Core 3 officially comes to Windows IoT Core

Setting up Free Custom Domain on Microsoft Azure Web App Service

Setting up CI and CD pipeline in Azure DevOps for ASP.NET Core and Azure Web Apps

Microsoft Azure DevOps : A Complete CI & CD solution in the cloud

Securing Powershell Scripts with Code-Signing Certificate

Understanding Powershell ExecutionPolicy and securing Powershell CmdLets/Scripts with Code-Signing Certificate

Microsoft Azure Blob Storage - Managing Blobs and storage containers from C#

Xamrin Android Push Notification using Firebase Cloud Messaging

Fundamental of Powershell Scripting