Friday, 27 September 2013

C# Delegates

                                                          Delegates  C#

What is Delegate -


1. A delegates is type safe function pointer  that is , it holds a reference(Pointer) to a  function.

2. The signature of a delegates must be the signature of of the function,the delegates  points to, otherwise you get a 
compiler  error .this is reason delegates are called as type safe function pointer.

3. A delegates is similar to a  class. you  can create an instance of it, and when you do so, you pass in the function name as a parameter
to the delegates constructor, and it is to this function the delegates will point to.

Note: The delegate syntax is similar to a method syntax with the delegates keyword.

Sample Code -

Sample Code  -
using System;

public delegate void hwllowworld(string strhellow);
  class  delegates
  {
         public static void Main(string[]args)
         {
             hwllowworld hw = new hwllowworld(add);
             hw("This is Ajay Chourasia");
         }

        public static void add( string strhellow)
        {
          Console.WriteLine(strhellow);
          Console.ReadKey();
        }

  }

Why need to Use Delegates -

You can call method directly on the object but consider following scenarios
  1. You want to call series of method by using single delegate without writing lot of method calls
  2. You want to implement event based system elegantly.
  3. You want to call two methods same in signature but reside in different classes
  4. You want to pass method as a parameter
  5. You don't want to write lot of polymorphic code like in Linq , you can provide lot of implementation to the Select method.

When to Use Delegates -

Use a delegate in the following circumstances:
  • An eventing design pattern is used.
  • It is desirable to encapsulate a static method.
  • The caller has no need to access other properties, methods, or interfaces on the object implementing the method.
  • Easy composition is desired.
  • A class may need more than one implementation of the method.

    MultiCastingDeligate

     "Invoking multiple methods in a single line," or "MultyCastDelegate is a linked list of Delegates."
     To do multicasting we have to assign multiple methods with the same signature to a single delegate. Let’s take an example; I got a requirement like, want to execute 2 methods in a single LOC i.e. one method to calculate area of circle and other to calculate area of square. And also one input value to drive both the methods. So our code will look like:
    Looking at the above code you can see that the signature of the delegate and the signature of the methods are matching and that the symbol += is used to attach the function to delegate. Let’s look at the output
     as we added functions with the help of +=, we can also remove the added method by the help
     of -= Using the same example, let's see how we can remove the added Method from the delegate. From the above example we have two methods added to the delegate, and now I am going to remove the method CalculateSquareAreafrom the delegate delCalc so the above code will look like this:
    See how I removed the method in the above snap shot? So what would our expected output be? The methodCalculateSquareArea will not be executed and the result will not be displayed in the output, right?
    As expected, the function was not executed and the result was not displayed .

    ---------------------------------------------------------------------------------------

    User Control Event Handler  

    In the previous section I tried to give you an overall idea of what a delegate is. In this section I am going to say how a delegate is related to an event.
    If there is an event then there must be an event handler to handle the event. Delegates are typically necessary when we are using user controls in ASP.NET applications to pull the event arguments to the parent page. Let's take a scenario and work on it.
    I would like to create an area calculating application for a circle, and I have also decided to make the area Calculator as a user control. The area calculator consists of one text box to enter the radius of a circle and a button to calculate the area, and the calculated area should be displayed in a label in the parent page, i.e. there is no provision in the User-control to display the result. So the question is, can we get the calculated area in our parent page from the user control?
    The answer is yes. We can achieve this with the help of Delegates and Events.
    Shall we start creating application? 
    First add an ASP.NET Project in your solution; I have added a Project called CsharpFeatures.
    In that project I have added one user control called ChildUserControll.ascx
    Don’t look at the other Project which you can see in the solution called Calculator; we are not going to use that right now.
    Let’s design the UI for the user control as I mentioned before. The UI will look like this:
    Let’s go and Plumb the inner side of User Control to take the result out. To make the calculation happen we want an event, right? So here we can do the calculation in our calculate button click event’s event handler. OK then. Do we get the button click event in the parent page in which the user control is consuming? Nooo ... we will not get the event or the output from the user control.
    To expose the event of the user control we have to add an additional event in our UserControll. If we are adding an event we want an event handler, right? And if we implement an event handler we want Event arguments, right? So what are all things we have to implement?
    We have to implement: Event, Eventhandler and Event arguments. OK, let’s see how we are going to implement all these things and how we are going to make use of delegates.
    As I mentioned before, I have already created an .ascx control. Inside the ascx control am going to add an Event:
    In the above snap shot I have added the Event called MyEvent, which is inside the class on top of page-load event; this is the event which will be exposed to public or to the aspx pages in which this user control is going to be consumed. Did you notice the type of MyEvent? It’s MyEventHandler. Do you think that is a system defined type? No, it's not.MyEventHandler is a delegate. What we are doing is attaching the event handler called MyEventHandler to the event called MyEvent. So what will be the input params of MyEvent? It will be of the MyEventHandler type, right? :) I hope you know how to declare a delegate. In either case I’ll show you the snap shot so that you can understand it a bit better.
    See the delegate? Does its signature look similar to anything you are familiar with? Yes. Just see below the Page_Loadevent’s parameters, one difference you can see is the EventArgs while in our delegate input it's MyEventArgs. The EventArgs is system defined Event arguments and MyEventArgs is defined by us. So what will be there in MyEventArgs? And what will be the input type of the MyEvent event?
    The MyEventArgs will contain the data to be returned from the user control after the execution of the functionality.
    So in our example what is the data to be returned? It’s the Area, right?
    Next I am going to show the MyEventArgs class. This class must be inherited from the System.EventArgs class. The class consists of one property: area.
    The area is of type double. For understanding and simplicity's sake I have started in the reverse order of construction. So what is the right order? First Create MyEventArgs, then go for MyEventHandler, and finally MyEvent which uses all the above three things. I hope you get the point. Here we have created the entire infrastructure that is required, but we didn’t really do anything. But if we didn’t start the calculation and didn’t assign any value to anything without doing this, how we are going to take the result out? Let’s go and do that.
    As I said earlier we are taking the result out of the control with the help of MyEventArgs. We have to set the calculated area in to the Area Property of the MyEventArgs for the user control. So go and do that.
    So in the above snap shot you can see what I have assigned the calculated Area to the MyEventArgs class. The next thing we have to do is take this result out of the control. But how? To take the result out of the control, the only way is through the event, so call the event with the arguments we have created. Like:
    This is how we call the event inside the button click by supplying the EventArgs. I have consumed the control, put a debugger, and executed just to show you what is passing out of the control. In this you can see what theobjEventArgs contains. Looks pretty good, right?  
    Now am going to tell you how we will consume the .ascx control and get the value displayed in the Label, which we have placed in the Default.aspx page. I hope you know how to place the .ascx control in .aspx page. Just drag and drop the control wherever you want. Then our default page will look as shown below upon executing the control.
    Let’s go to the Default.aspx page Page_Load event and make the necessary changes. Once we add the UserControll in to the Parent page what actually happens is the object of the user control is created in that parent page. In the below snap shot you can see this. Here, by adding the ChildUserControll in the page I get the ChildUserControll 1object.
    You can also see the event which we have declared inside the user control in the intellisense of the object. So let’s go and add the event handler for the event in the page.
    In the tool tip you will see Press TAB to insert. Hit the tab key two times so VS will create an event handler stub for us. You can also see that the type of event handler that is going to be created is of MyEventHandler type, which is the delegate we created for MyEvent handling. All looks well and good :)
    After hitting tab the event handler stub got generated and I started plumbing to get the area displayed in the label in the parent page. Refer to the above snapshot. In the intellisense the Area property is of type double. It’s really amazing, right?
    The entire code is shown below:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Diagnostics;
     
    namespace CsharpFeatures
    {
        public partial class _Default : System.Web.UI.Page
        {  
            protected
    void Page_Load(object
    sender, EventArgs e)
            {
               ChildUserControll1.MyEvent+=new MyEventHandler(ChildUserControll1_MyEvent);
            }
     
            void
    ChildUserControll1_MyEvent(object sender, MyEventArgs e)
            {
                lblResult.Text = e.Area.ToString();
            }
     
        }}
    Look at the output and check whether the result is getting displayed in the label in the parent page.
    Wow! It’s an amazing mechanism, right? Delegates are simply amazing.
    OK, here I am going to write one single simple scenario where we can use delegates. Did you ever think of loosely coupling our applications using delegates? Yes, we can also develop loosely coupled applications using delegates to an certain extent. I’ll show how we can do this loose coupling. :)
    Did you notice one project in our solution explorer called Calculator? I am going to make use of this project and we are going to create a simple calculator which performs three arithmetical operations like Add, Subtract and Multiply with two input integer values. For this I have created one more project (called calculator) as a layer in our solution itself, and I have written the calculation logic inside the Calculator Layer.
    Let’s see how I have written the Calculator Layer. Inside the layer I have created a class called MyCalculator. It is here where I am going to write the calculate logic. So what is the role of decoupling or loosely coupling in a simple calculator? There is a large scope for these terms here. Let's set everything aside and think about how can we create an application like a calculator with two layers I.E. presentation layer and business layer.
    We will write three public methods in the Calculator layer then will call the methods from the consuming client according to our operation. This requires the help of an if condition or a switch statement. So if we want to add more functionality to our application, what will we do? We have to go and write a method (say, Divide) in the Calculator layer and again make a change in the consuming application to accommodate the change made in theCalculator layer.
    The UI Layer and the Calculator Layer(BLL) is tightly coupled. In addition, the consuming end will eventually know all the methods or operations in the Calculator layer because we are using Public methods. So how can we avoid the situation? There are several different ways to deal with this scenario. I am going to explain how we will do this with the help of delegates.
    Let’s look at the UI of the application we are using. Look like below snap shot:
    Two text boxes which can be used to enter numeric values and perform arithmetic operations, which displayed in the dropdown. Looks cool.
    Let’s go and look in to the Calculator Layer and see what all plumbing I have done. As previously stated, we are going to solve this issue with the help of delegates so we want a delegate for sure and also ensure the access specifier must be private. Then only the Calculator Layer can hide the methods within it, right? So let’s go and see what is there in the Calculator Layer.
    So you can see one delegate called DelegateMyCalculator which accepts two integer type input parameters and returns integer type data. You can also see three private methods defined in the class. As the next step let’s go and attach the delegate to the methods. Here is the tricky part, as before we are not directly assigning methods to delegates but creating a method with the return type of delegate (DelegateMyCalculator), which also accepts onestring type of input parameter.
    So looking at the above snap shot you can see the marked line of code. In the first one the delegate method is calledCalculate, which accepts an input parameter of string type, then inside that method we have created an object of the delegate (DelegateMyCalculator) and assigned it to null. You can also clearly see that the assigning to the delegate is done only once, and only to one method according to the input of the Calculate method. Let’s go and consume the method from our UI Layer.
    Here is one question which will rock your world: How can we call a delegate method? How can we supply the input values to the delegate method from the UI? The method accepts only one input parameter, right? Go and see the plumbing of UI layer.
    What I have done is created an object of the MyCalculator class. Let’s see all the methods the object is displaying in the intellisense:
    You can see the method called Calculate which is of type DelegateMyCalculator and is also visible in the tool tip. We don’t have any other methods displayed so the UI will not know all operations are in the Calculator layer (BLL). That’s one intention. We will be passing the operation as a selected value from the drop-down list to the Calculatemethod.
    Next we pass the input parameters to the method. Let's just see what is in the intellisense of Calculate method call.
    Here you can see the magic. There is one method called Invoke which accepts two input parameters and both are integer. What will happen if we use this method by passing the values of the textboxes as parameters to Invoke as integer? What will the LOC will look like?
    And one more thing I have done is assigned the return value to a label in our UI Layer. Go and execute the application and see what happens.
    See? It worked fine 10 + 10= 20; the result is displayed in the label as assigned. We can say that the application is loosely coupled because if we want to add one more functionality, we can go and add one method in the Calculator layer (say, divide) then do a very minute change in the UI I.E. to add one operation (Divide) in the drop-down list. You can add methods in the immediate layer with far less changes in preceding or succeeding layer.