Friday, June 8, 2012

Delegates in C#

Delegates are similar to Function Pointers in C++, as the name implies delegates can point to any function which shares the same signature of the delegate.

A Delegate is used to hold a reference of a method, the method referred by the delegate can be changed dynamically.

Delegates can also reference more than one method at the same time, these delegates are called Multi-cast delegates.

Delegates can be used to make asynchronous calls to method, so that the calling method can continue with its own operation, and the method referenced the delegate will execute in parallel. This feature comes in handy when we need to perform calls to long running methods without making the user to wait for the process to get completed. A callback function can be associated with the delegate call so that the long running method calls the main method once its processing is completed.

Let us consider a simple calculator example, which can perform 4 operations using the following 4 methods.

private string Add(int nNumber1, int nNumber2)
{
    return "Add => " + (nNumber1 + nNumber2).ToString() + "";
}
//
private string Subract(int nNumber1, int nNumber2)
{
    return "Subract =>" + (nNumber1 - nNumber2).ToString() + "";
}
//
private string Multiply(int nNumber1, int nNumber2)
{
    return "Multiple => " + (nNumber1 * nNumber2).ToString() + "";
}
//
private string Divide(int nNumber1, int nNumber2)
{
    return "Divide => " + (nNumber1 / nNumber2).ToString() + "";
}

Let us desing a simple .aspx page as follows.




The user can enter 2 numbers in the Textboxes, select the operation in the Dropdown and click on the Evaluate button to perform the calculation.

Now let us declare a Delegate to call the appropriate operation selected by the user.
The signature of the delegate should match the signature of the methods with which it will be associated, here the 4 methods take 2 integers as parameters and return a string, hence we will declare a delegate with the same signature.

public delegate string delMath(int nNumber1, int nNumber2);

In the Click event of the Evaluate button, we shall initialize the Delegate and make it point to the appropriate method, based on the option selected by the user.
//
protected void cmdEvaluate_Click(object sender, EventArgs e)
{
    delMath myDelegate = null;
    //
    switch (drpOperation.SelectedValue)
    {
        case "Add":
            {
                myDelegate += new delMath(Add);
                break;
            }
        case "Subract":
            {
                myDelegate += new delMath(Subract);
                break;
            }
        case "Multiply":
            {
                myDelegate += new delMath(Multiply);
                break;
            }
        case "Divide":
            {
                myDelegate += new delMath(Divide);
                break;
            }
    }
    //
    lblResult.Text = myDelegate(Convert.ToInt16(txtNumber1.Text),  Convert.ToInt16(txtNumber2.Text));
}

Finally we are just calling the Delegate and passing the values entered by the user, note that we are not calling the method directly, the delegate will in turn call the referenced method and handle the return values.


The complete code for the example is as follows
.aspx page
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Delegates</title>
</head>
<
body>
<form id="frmDelegates" runat="server">
Enter Number1 <asp:TextBox
ID="txtNumber1"
runat="server">
</asp:TextBox> <br />

Enter Number2 <asp:TextBox
ID="txtNumber2"
runat="server">
</asp:TextBox> <br />

Select Operation

<asp:DropDownList
ID="drpOperation"
runat="server">
            <asp:ListItem
Value="Add"
Text="Add">
</asp:ListItem>
            <asp:ListItem
Value="Subract"
Text="Subract">
</asp:ListItem>
            <asp:ListItem
Value="Multiply"
Text="Multiply">
</asp:ListItem>
            <asp:ListItem
Value="Divide"
Text="Divide">
</asp:ListItem>
</asp:DropDownList>

<asp:Button
ID="cmdEvaluate"
runat="server"
Text="Evaluate"
      onclick="cmdEvaluate_Click" />
<br /><br />

Result Expression:
<asp:Label ID="lblResult" runat="server"></asp:Label>
</form>
</body>
</
html>

.aspx.cs file
public partial class Delegates : System.Web.UI.Page
{
    public delegate string delMath(int nNumber1, int nNumber2);
    //
    protected void cmdEvaluate_Click(object sender, EventArgs e)
    {
        delMath myDelegate = null;
        //
        switch (drpOperation.SelectedValue)
        {
            case "Add":
                {
                    myDelegate += new delMath(Add);
                    break;
                }
            case "Subract":
                {
                    myDelegate += new delMath(Subract);
                    break;
                }
            case "Multiply":
                {
                    myDelegate += new delMath(Multiply);
                    break;
                }
            case "Divide":
                {
                    myDelegate += new delMath(Divide);
                    break;
                }
        }
        //
        lblResult.Text = myDelegate(Convert.ToInt16(txtNumber1.Text), Convert.ToInt16(txtNumber2.Text));
        //
    }
    //
    private string Add(int nNumber1, int nNumber2)
    {
        return "Add => " + (nNumber1 + nNumber2).ToString() + "</br>";
    }
    //
    private string Subract(int nNumber1, int nNumber2)
    {
        return "Subract =>" + (nNumber1 - nNumber2).ToString() + "</br>";
    }
    //
    private string Multiply(int nNumber1, int nNumber2)
    {
        return "Multiple => " + (nNumber1 * nNumber2).ToString() + "</br>";
    }
    //
    private string Divide(int nNumber1, int nNumber2)
    {
        return "Divide => " + (nNumber1 / nNumber2).ToString() + "</br>";
    }
    //
    protected void Page_Load(object sender, EventArgs e)
    {

    }
}






At this point it might look like the Delegate is nothing special, we feel like we could have called the methods directly based on the option selected by the users, but this is just a basic introduction for the delegates, delegates have many other advanced features like Event Handling, Callbacks, Multi-cast Delegates, Asynchronous calls which makes the delegates more important, to understand these concepts we should be aware of the basics of Delegates, this post is intended to give only the basics, we shall see the advanced features in the subsequent posts.


Related Posts
Delegates in C#
Multicast Delegates
Event handling using Delegates in C#
Synchronous call using Delegates in C#
Asynchronous callback using Delegates in C#


Search Flipkart Products:
Flipkart.com

No comments: