Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the benefits of having events conforming to Net guidelines?

Tags:

c#

.net

events

I understand how to use Events according to Net Framework guidelines, but what are the benefits of using this pattern?

http://msdn.microsoft.com/en-us/library/aa645739%28VS.71%29.aspx :

The .NET Framework guidelines indicate that the delegate type used for an event should take two parameters, an "object source" parameter indicating the source of the event, and an "e" parameter that encapsulates any additional information about the event. The type of the "e" parameter should derive from the EventArgs class. For events that do not use any additional information, the .NET Framework has already defined an appropriate delegate type: EventHandler.

a) I see some benefits in using "object source" value as a first parameter since there are situations where multiple objects can have their events set to the same method. Thus, if for example we have 10 objects and if all 10 objects set their events to event handler M, then inside M we can use “object sender” parameter value to identify the initiator of the event call.

  • But as far as I can tell, ”object source” parameter is only useful if event was raised inside an instance method. Thus, if event was raised inside static method, then “object source” parameter is of no use?!

b) Are there other benefits of using events with accordance to Net Framework guidelines?

c) Whatever the benefits may be, why would they out-weight the trouble of having to

  • write an additional code to put the desired arguments into an object derived from EventArgs
  • write an additional code inside event handlers to extract information from object derived from EventArgs ?

thank you

like image 794
AspOnMyNet Avatar asked Feb 17 '10 17:02

AspOnMyNet


2 Answers

As far as I see it there are two major benefits:

  • People writing code consuming the event will recognize the pattern and immediately know how to use the event
  • The signature of the event is crafted in a way that it is robust towards change

The first point should be pretty obvious, not needing a lot of elaboration.

As for the second point, there are two reasons for this (in my opinion). First, since sender is object, the event signature can be reused by several types. Second, since the second parameter is an EventArgs decendant, when you introduce your own EventArgs class this class can be extended later without altering the signature of the event.

Update
Response to questions:

I’m not sure what you mean by “ being able to extend EventArgs without altering the signature of the event”?!

Let's take an example, take the following class:

public class SomeClass
{
    public event EventHandler<FileEventArgs> SomethingHappened;
}
public class FileEventArgs : EventArgs
{
    public FileEventArgs(string filename)
    {
        Filename = filename;
    }
    public string Filename { get; private set; }
}

Then we have a consumer that listens to the SomethingHappened event:

static void SomethingHappenedHandler(object sender, FileEventArgs e)
{
    // do something intelligent
}

Now, lets say that we want to extend the information that we transfer in the event with information about what happened to the file:

public enum WhatHappened
{
    Copy,
    Rename,
    Delete
}
public class FileEventArgs : EventArgs
{
    public FileEventArgs(string filename, WhatHappened whatHappened)
    {
        Filename = filename;
        WhatHappened = whatHappened;
    }
    public string Filename { get; private set; }
    public WhatHappened WhatHappened { get; private set; }
}

Now, if we had chosen to send the filename as a parameter in the event itself, we would need to alter the event signature by adding another parameter, effectively breaking all code that listens to the event. But since we in the code above have simply just added another property to the FileEventArgsclass, the signature remains unchanged, and no listeners need to be updated (unless they want to use the newly added property, that is).

Am I write in assuming that if event is raised inside static method, then “object source” parameter is of no use?!

Yes, that is correct. I typically pass null as the sender argument from static events (which, honestly, is very rare).

like image 77
Fredrik Mörk Avatar answered Sep 28 '22 16:09

Fredrik Mörk


If you adhere to the .NET Framework guidelines, not only for events, but for everything, someone who needs to read your code or use your library will recognize it, making things simpler for him. This is always a good thing, since you should write code for your readers, not for your convenience. The good thing with .NET is that there is some standard guideline right from the beginning, in contrast to the thousands of conventions for C++ and the like, and most people know it and apply it.

The added benefit of the standard event handler signature is that you can assign less specialized event handlers (like, say, EventHandler) to an event of a more specialized type, simplifying development if someone does not need the additional data. It also makes it simpler to add event handlers via Reflection, which may be useful in certain circumstances (like an object hierarchy browser for some object model) - I can assure you that code to handle any event via Reflection is a complicated thing which I solved by emitting IL code for each event, which I'd always regard as a last resort.

As Fredrik Mörk wrote in the mean time, this makes it also easier to extend your event later by adding parameters just to your EventArgs-derived class, rather than to each and every event handler.

like image 43
OregonGhost Avatar answered Sep 28 '22 17:09

OregonGhost