static void

Events and Delegates

A delegate is an object representing a function pointer. It is defined with a method signature (the return type and argument).

public delegate string MyDelegate(bool isOK);

An event tells subscribers that they must use a method that looks like the delegate.

public event MyDelegate MyEvent;

In .Net 2 you can avoid creating a delegate with the generic EventHandler (msdn)

public event EventHandler<MyEventArgs> MyEvent;

Declare Event

A generic EventArgs<T> : EventArgs is handy for passing strong typed data (strings, int, object)

public class Worker

{

    public event EventHandler<GenericEventArgs<string>> WorkDone;

    public void Execute(string m)

    {

      EventHandler<GenericEventArgs<string>> handler = WorkDone;

      if (handler != null) handler(this, new GenericEventArgs<string>(m));

    }

}

 

public class GenericEventArgs<T> : EventArgs

{

    private T _data;

    public GenericEventArgs(T data)

    {

        _data = data;

    }

    public T Data

    {

        get { return _data; }

        set { _data = value; }

    }

}

Raise Event

To raise the event (publish it):

//cast the delegate as the event. If there is no subscriber, the event is null
MyDelegate handler = MyEvent;
if (handler != null) handler(this, args);

You must use the raise event pattern (see C# faq). NB: if you don't assign the copy, it's not thread safe (there's a race condition between the check and the useage).
if (MyEvent != null) MyEvent(this, EventArgs.Empty); //compiles but not thread safe!!
EventHandler handler = MyEvent; //do this
if (handler != null) handler(this, EventArgs.Empty);

Consume Event

To consume it from a subscriber:

WorkClass wc = new WorkClass(); //scope needs to be class level
wc.MyEvent += new WorkClass.MyDelegate(MySubscriberMethod); //the new EventHandler syntax is optional...
wc.MyEvent += MySubscriberMethod; //works too!

You can inline it and use local variables:

decimal totalWeight; // Local

wc.FoundWeight +=

    (delegate(object sender, GenericEventArgs<decimal> e) { totalWeight += e.Data; });

//or v3 lamdba style

shipper.RecordCTotalWeight += ((sender, e) => totalWeight += e.Data);