.NET Delegates: A C# Bedtime Story

Events

Events

Unfortunately, the Universe being very busy and unaccustomed to paying attention to individuals, has managed to replace Peter's boss's delegate with its own. This is an unintended side effect of making the delegate fields public in Peter's Worker class. Likewise, if Peter's boss gets impatient, he can decide to fire Peter's delegates himself (which is just the kind of rude thing that Peter's boss was apt to do):

        // Peter's boss taking matters into his own hands
        if( peter.completed != null ) peter.completed();

Peter wants to make sure that neither of these can happens. He realizes he needs to add registration and unregistration functions for each delegate so that listeners can add or remove themselves, but can't clear the entire list or fire Peter's events. Instead of implementing these functions himself, Peter uses the event keyword to make the C# compiler build these methods for him:

class Worker {
...
    public event WorkStarted started;
    public event WorkProgressing progressing;
    public event WorkCompleted completed;
}

Peter knows that the event keyword erects a property around a delegate, only allowing C# clients to add or remove themselves with the += and -= operators, forcing his boss and the universe to play nicely:

    static void Main() {
        Worker  peter = new Worker();
        Boss        boss = new Boss();
        peter.completed += new WorkCompleted(boss.WorkCompleted);
        peter.started += new WorkStarted(Universe.WorkerStartedWork);
        peter.completed += new WorkCompleted(Universe.WorkerCompletedWork);
        peter.DoWork();
        Console.WriteLine("Main: worker completed work");
        Console.ReadLine();
    }

Harvesting All Results

At this point, Peter breathes a sign of relief. He has managed to satisfy the requirements of all his listeners without having to be closely coupled with the specific implementations. However, he notices that while both his boss and the universe provide grades of his work that he's only receiving one of the grades. In the face of multiple listeners, he'd really like to harvest all of their results. So, he reaches into his delegate and pulls out the list of listeners so that he can call each of them manually:

    public void DoWork() {
        ...
        Console.WriteLine("Worker: work completed");
        if( completed != null ) {
            foreach( WorkCompleted wc in completed.GetInvocationList() ) {
                int grade = wc();
                Console.WriteLine("Worker grade= " + grade);
            }
        }
    }

You might also like...

Comments

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“A computer lets you make more mistakes faster than any other invention in human history, with the possible exceptions of handguns and tequila” - Mitch Ratcliffe