Peet Brits

Hmm, but that doesn't make any sense…

Posts Tagged ‘delegates’

Introduction to C# Delegates and Events

Posted by Peet Brits on August 3, 2010

Delegate: A person appointed or elected to represent others.

In programming a delegate, or a method definition or a function pointer, represents a reference or pointer to a method. In C++ it had many confusing stars and brackets, but in C# the definition is rather simple:

// Delegate / method definition
public delegate void NodeEvent(object sender, bool reloadOnly);

The second concept related to delegates is Events. Events conform to the definition of the delegate. Any code can use a delegate, but only the containing class can throw events. This provides an easy construct for external code to subscribe to and unsubscribe from events.

// Event definition, conforming the the delegate "NodeEvent"
public event NodeEvent BeforeExpandNode;

// SUBSCRIBE SAMPLE (this happens in the client code)

listBrowser.BeforeExpandNode += new NodeEvent(listBrowser_BeforeExpandNode);

// TIP: in VS, when you type '+=' and press tab, the designer
// will automatically generate the method definition

// The definition of this method is the same as the delegate "NodeEvent"
void listBrowser_BeforeExpandNode(object sender, bool reloadOnly)
{
    // ...
}

// Optionally, you can add/remove methods in a much simpler way:
listBrowser.BeforeExpandNode += listBrowser_BeforeExpandNode;   // Add (subscribe)
listBrowser.BeforeExpandNode -= listBrowser_BeforeExpandNode;   // Remove (unsubscribe)

The above same shows how events allow you to call a list of methods at once by calling the single method “listBrowser.BeforeExpandNode.” The attached methods will trigger in the order that they were attached. It is the client’s responsibility to ensure that the called methods are exception safe. If the attached method throws an exception then the entire list will be abandoned.

// THROW EVENT SAMPLE (this happens in the class where the event is defined)

protected void OnBeforeExpandNode(object sender, bool reloadOnly)
{
    // I am lazy to type this out every time, so I put it in a method.
    // In programming, lazy usually means efficient.

    // Private variable to ensure thread safety
    var handler = BeforeExpandNode;
    if (handler != null)
    {
        // This will call everything subscribed to it.
        // In our example this is "listBrowser_BeforeExpandNode()"
        handler(sender, reloadOnly);
    }
}

// Usage sample:
private void ExpandNode()
{
    // Add custom checks here
    // ...

    // Now raise the "BeforeExpandNode" event
    OnBeforeExpandNode(this, false);

    // Now continue to expand the node
    // ...
}

Comparing the two, you can only invoke events from with the declared class, but any class can use delegates. Interfaces can specify events, but not delegates. Events can override Add/Remove method accessors. For more differences, see this comparison between delegates and events.

That is it! Now you know how to use basic delegates and events. As a bonus, here is an additional sample:

// When registering an event it is possible to use a delegate instead of the actual method.
// I prefer to avoid this, because it makes debugging much harder.
btn.Click += delegate(object sender, RoutedEventArgs e) { ... };
Advertisements

Posted in Code (Programming) | Tagged: , , , , | Leave a Comment »