Events and Delegates - Part I

by agrace 1. September 2007 09:46

This is part one of a series of posts on events and delegates, a powerful means of implementing loosely-coupled designs. This part will focus on delegates. You can read part two here.

Introduction

As a developer, I think it took me longer than necessary to get my head around the code details of the event/delegate paradigm. In retrospect, I believe this was mainly due to my lack of understanding of the delegate type, which connects everything together.

Another problem I encountered was a lack of consistency of language and definitions used by the authors of books and articles on events and delegates. More on this later.

Publishers + Subscribers = Observer Pattern

 

There is no need to have a PhD in anonymous methods, function pointers, multicast versus single cast delegates and the like, in order to get started with events. What you do need is a basic understanding of the central piece of the jigsaw: the delegate. Next, you need to get an overview of the Publish-Subscribe model. Finally, you need to open up your code editor and create a basic event sample for yourself.

Overview

Generally, delegates (or callbacks) are typesafe pointers to methods, similar to function pointers in C++. We can use delegates to specify callbacks and also to register handlers for GUI events like button clicks. Unlike function pointers, which can only contain the address of a static method, a delegate can refer to instance methods in classes - this is what makes them tremendously useful. A delegate is like an interface: the difference is that the delegate declares a single static or reference method, whereas the interface can declare several methods. Whenever we want classes to communicate with less coupling than with an interface, we should use a delegate. In other words, delegates are not only for use with events!

If we need to specify an action or method in advance and we don't know which method, or even object, that will perform this action, we should use a delegate. For example, we can connect a button to a delegate and at runtime we can resolve that delegate to a particular method to be run.

Delegates

A delegate is a special type in .NET whose main role in life is to hold a reference to a method. Delegates are defined with a signature, much like methods, and can only hold a reference to a method which matches this signature. We declare a delegate by using the "delegate" keyword and specifying the signature of the method to which it holds a reference. The following is a declaration of a delegate that can reference a method that takes two parameters and does not return a value:

public delegate void EventHandler(object sender, EventArgs e);

 

The delegate is a TYPE; think of the entire statement above as a type. A method matching this signature would look like this:

public void Button_Clicked(object sender, EventArgs e);

 

In the following example, the delegate called SampleDelegate can invoke any method that is passed a string parameter and returns an int:

delegate int SampleDelegate(sting str);

 

We can now initialize a new delegate, like so...

SampleDelegate del = new SampleDelegate(DoSomething);

 

 ... and can call the delegate as follows:

del(someString);

 

Terminology

A final point regarding terminology. When we talk about classes, we use two separate terms: class and object. With delegates, there is only a single term. An instance of a delegate class is also known as a delegate. So, we need to pay attention to context here. I will come back to the issue of terminology in the next post which will focus on events.

Tags: ,

ASP.NET | C#




I recently had to implement a pair of cascading DropDownLists for an ASP.NET Web project and found very little workable code samples on Google. Here's the code that worked for me.

The second DropDownList is enabled based on the selection made in the first and the cascade works in both directions, depending on the selection. The tricky bit was getting the index of the selection in the second drop down. I eventually found samples of the IndexOf and FindByText ListItemCollection methods on the MSDN site.

    <asp:DropDownList ID="InstrumentDDL" AutoPostBack="true"  
        OnSelectedIndexChanged="InstrumentDDL_SelectedIndexChanged"
            Width="100" runat="server">
        <asp:ListItem Text="Select" Value="Select"></asp:ListItem>
        <asp:ListItem Text="Guitar" Value="Guitar"></asp:ListItem>
        <asp:ListItem Text="Mandolin" Value="Mandolin"></asp:ListItem>
    </asp:DropDownList>

    <asp:DropDownList ID="GuitarDDL" AutoPostBack="true"  
        OnSelectedIndexChanged="GuitarDDL_SelectedIndexChanged"
            Enabled="false" Width="100" runat="server">
        <asp:ListItem Text="Select" Value="Select"></asp:ListItem>
        <asp:ListItem Text="Fender" Value="Fender"></asp:ListItem>
        <asp:ListItem Text="Gibson" Value="Gibson"></asp:ListItem>
        <asp:ListItem Text="Gretsch" Value="Gretsch"></asp:ListItem>
        <asp:ListItem Text="Martin" Value="Martin"></asp:ListItem>
    </asp:DropDownList>

    protected void InstrumentDDL_SelectedIndexChanged(object sender, EventArgs e)
    {
        // Reset GuitarDDL
        GuitarDDL.SelectedIndex = -1;

        // Dynamically enable the GuitarDDL based on InstrumentDDL selection
        if (InstrumentDDL.SelectedValue == "Guitar")
        {
            GuitarDDL.SelectedItem.Text = "Select";
            GuitarDDL.Enabled = true;
        }
        else
        {
            GuitarDDL.SelectedItem.Text = GuitarDDL.SelectedValue;
            GuitarDDL.Enabled = false;
        }
    }

    protected void GuitarDDL_SelectedIndexChanged(object sender, EventArgs e)
    {
        // Every menu item refers to "Guitar" in the InstrumentDDL menu (except "Select")
        if (GuitarDDL.SelectedValue == "Select")
        {
            // Reset InstrumentDDL menu and disable the GuitarDDL menu
            InstrumentDDL.SelectedIndex
                = InstrumentDDL.Items.IndexOf(InstrumentDDL.Items.FindByText("Select"));
            GuitarDDL.Enabled = false;
        }
        else
        {
            InstrumentDDL.SelectedIndex
                 = InstrumentDDL.Items.IndexOf(InstrumentDDL.Items.FindByText("Guitar"));
        }
    }

 


Welcome to CodersBarn.com

by agrace 10. June 2007 21:26

Here goes... I guess I've been gleaning the goods from other people's sites long enough! They say committing to a blog is a time-consuming venture. I've decided to get this site out fast and then add to it gradually. The main motivation behind this blog is to create a forum where developers like myself can discuss programming and design issues. I want to encourage beginners and experts alike to make this site a place where people can have fun and learn at the same time. 

I have been reading Mads Kristensen's blog and it is his Blog Engine that is under the hood. I have been using ASP.NET and C# for around three years. I'm no expert but was able to download Mads' Blog Engine this afternoon and have it up and running in no time. I made some minor changes to the theme stylesheet and that was it. The previous night, while browsing through iStockphoto I came across the banner picture you see above. This morning, I took one look at it and the domain name just jumped out at me. Five minutes later, I had it registered on GoDaddy and this baby was born!

This is a really exciting time for Web Developers in general. Hopefully, some of the subjects that interest me personally will be representative of some of the new technologies emerging in our industry as we look forward. Please email me if you have any thoughts about interesting directions this site could possibly take.

I am currently embarking on the Ajax and SharePoint learning curve but ASP.NET 2.0 is still the main focus of my work and future posts will probably reflect that.

Anthony Grace :-)

 

Tags: ,

ASP.NET | C#