Thursday, April 21, 2016

Events using EventHandler in C#

In today's post, I will be discussing Events using Event Handler in C#. This is in continuation with the previous week post here.

Events without using Delegates keyword explicitly

Last week we discussed what events are and how to use them in our application. We saw how to use events using delegates here. That post was more to show what's going on behind the scenes. The .NET framework has special guidelines on the delegates that can be used for events. The delegate type should have an object parameter and EventArgs parameter and should return void. So the .NET framework has defined a special delegate type called EventHandler for this purpose.

So the last week's example, if we were using EventHandler, will be as follows:


public class ListWithChangedEvent : ArrayList
{
    public event EventHandler Changed;
    protected virtual void OnChanged(EventArgs e)
    {
            if (Changed != null)
                Changed(this, e);
     }

    public override int Add(object value)
    {
        int i = base.Add(value);
         OnChanged(EventArgs.Empty);
        return i;
    }

    public override void Clear()
    {
        base.Clear();
        OnChanged(EventArgs.Empty);
    }

    public override object this[int index]
    {
        set
        {
            base[index] = value;
            OnChanged(EventArgs.Empty);
        }
    }
}

There is no delegate keyword being used explicitly and we just used EventHandler.

Internally, the EventHandler looks like as follows:

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

So, to use the list we can do it the same way as previous post mentioned above:

static void Main(string[] args)
{
     ListWithChangedEvent list = new ListWithChangedEvent();
     list.Changed += ListChanged;
     list.Add("item 1");
     list.Clear();
     Console.ReadLine();
}

private static void ListChanged(object sender, EventArgs e)
{
     Console.WriteLine("This is called when the event fires without delegate.");
}

The list triggers event anytime the list items are changed.

Conclusion

So we saw a simple example of delegates usage using EventHandler. Using EventHandler helps us follow the .NET framework guidelines and adhere to the standard. It's good to know how the delegates work behind the scenes.

For future updates to my weekly blog, please subscribe to my blog via the "Subscribe To Weekly Post" feature at the right and follow me on Twitter. Until then Happy Coding :)


Reference: MSDN

2 comments:

  1. It's clearer to say "without defining your own delegate types" than to say "without using delegates explicitly." Whether you are using a base class library delegate type or your own delegate type, you are using delegates explicitly when you type "var handler = Changed; if (handler != null) handler(this, e)", because handler is a delegate and Changed is referring to a delegate field and you are comparing the delegate to null and invoking the delegate. That's using delegates pretty explicitly, no matter what the delegate type is.

    Technically you can't avoid using delegates explicitly in C#. C# forces you to use delegates explicitly every time you raise an event. In VB.NET you can avoid using delegates explicitly with the RaiseEvent keyword for which C# has no analog.

    Also, did you know you can use the generic EventHandler<T> in cases where you have your own class which extends EventArgs? That means you never need to define your own delegate type for events. It's really cool. You'll see a ton of BCL delegates from .NET v1 before there was language support for generics.

    ReplyDelete
  2. Hi Joseph,
    Thanks for pointing that out. You are right that Changed is a delegate. The reason why I put it that way just that we are not using the delegate keyword specifically. Also, good to know about VB.NET RaiseEvent :)
    Regarding generic event handler, that's indeed in plan- it's the next post coming soon :) Thanks again!

    ReplyDelete