.NET Delegates: A C# Bedtime Story

Delegates & Static Listeners

Delegates

Unfortunately, Peter was so busy talking his boss into implementing this interface that he didn't get around to notifying the Universe, but he knew he would soon. At least he'd abstracted the reference of his boss far away from him so that others who implemented the IWorkerEvents interface could be notified of his work progress.

Still, his boss complained bitterly. "Peter!" his boss fumed. "Why are you bothering to notify me when you start your work or when your work is progressing?!? I don't care about those events. Not only do you force me to implement those methods, but you're wasting valuable work time waiting for me to return from the event, which is further expanded when I am far away! Can't you figure out a way to stop bothering me?"

And so, Peter decided that while interfaces were useful for many things, when it came to events, their granularity was not fine enough. He wished to be able to notify interested parties only of the events that matched their hearts' desires. So, he decided to break the methods out of the interface into separate delegate functions, each of which acted like a little tiny interface of one method each:

delegate void WorkStarted();
delegate void WorkProgressing();
delegate int WorkCompleted();
class Worker {
    public void DoWork() {
        Console.WriteLine("Worker: work started");
        if( started != null ) started();
        Console.WriteLine("Worker: work progressing");
        if( progressing != null ) progressing();
        Console.WriteLine("Worker: work completed");
        if( completed != null ) {
            int grade = completed();
            Console.WriteLine("Worker grade= " + grade);
        }
    }
    public WorkStarted started;
    public WorkProgressing progressing;
    public WorkCompleted completed;
}
class Boss {
    public int WorkCompleted() {
        Console.WriteLine("Better...");
        return 4; /* out of 10 */
    }
}
class Universe {
    static void Main() {
        Worker  peter = new Worker();
        Boss        boss = new Boss();
        peter.completed = new WorkCompleted(boss.WorkCompleted);
        peter.DoWork();
        Console.WriteLine("Main: worker completed work");
        Console.ReadLine();
    }
}

Static Listeners

This accomplished the goal of not bothering his boss with events that he didn't want, but still Peter had not managed to get the universe on his list of listeners. Since the universe is an all-compassing entity, it didn't seem right to hook delegates to instance members (imagine how many resources multiple instances of the universe would need...). Instead, Peter need to hook delegates to static members, which delegates support fully:

class Universe {
    static void WorkerStartedWork() {
        Console.WriteLine("Universe notices worker starting work");
    }
    static int WorkerCompletedWork() {
        Console.WriteLine("Universe pleased with worker's work");
        return 7;
    }
    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();
    }
}

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.

“There's no test like production” - Anon