Why should events in C# take (sender, EventArgs)? - c#

It's known that you should declare events that take as parameters (object sender, EventArgs args). Why?

This allows the consuming developer the ability to write a single event handler for multiple events, regardless of sender or event.
Edit: Why would you need a different pattern? You can inherit EventArgs to provide any amount of data, and changing the pattern is only going to serve to confuse and frustrate any developer that is forced to consume this new pattern.

Actually this is debatable whether or not this is the best practice way to do events. There is the school of thought that as events are intended to decouple two segments of code, the fact that the event handler gets the sender, and has to know what type to cast the sender into in order to do anything with it is an anti-pattern.

Because it's a good pattern for any callback mechanism, regardless of language. You want to know who sent the event (the sender) and data that is pertinent to the event (EventArgs).

Using a single parameter, EventArgs, for the data passed by an event allows you to add data to your event in future versions of your software without breaking existing consumers. You simply add new members to an existing EventArgs-derived class, or create a derived class with the new members.
Otherwise consistency and the principle of least surprise justify using EventArgs for passing data.
As for sender, in some (but not all) cases it's useful to know what type sent the event. Using a type other than object for the sender argument is too restrictive: it would mean that other senders couldn't reuse the same event signature.

It is a good pattern to use, that way what ever implements the event can find what was sending it.
Also overriding the EventArgs and passing data through them is the best method. The EventArgs are a base class. If you look at various controls that call events, they have overridden EventArgs which gives you more information about the event.
Even if you don't need the arguments to do the event, if you do not include them with the first run of the framework and want to add them later, you break all previous implementations, and have to re-write them. Plus if you a creating a framework and going to distribute that it becomes worse because everybody that uses your framework will need to refactor.

Chris Anderson says in the Framework Design Guidelines book:
[T]his is just about a pattern. By having event arguments packaged in a class you get better versioning semantics. By having a common pattern (sender, e) it is easily learned as the signature for all events.
There are situations mostly involving interop that would require deviation from this pattern.

It seemed that this was Microsoft's way to evolve the event model over time. It also seems that they are also allowing another way to do it with the "new" Action delegate and it's variations.

Sometimes you would like to force all of your event consumers to use a particular event parameter, for example, a security event which passes a boolean parameter, true for good, false for bad.
In this case you want your consumer to be painfully aware of the new parameter, i.e. you want your consumers to be coupled with that parameter. Take note, your consumers are still decoupled from your event firing class, but not from your event.
I suspect that this scenario applies to a large number of cases and in those cases the value of EventArgs is greatly reduced.

"Object sender" allows to reuse one method for multiple objects when the handler method is supposed to do something with the object that raised the event, for example 3 textbox can have one single handler that will reset the text of the firing textbox.
EventArgs's main advantage is that it allows to refactor event information without the need to change signatures of all handlers in all projects that are subscribed to this kind of event.
I can't think of a smarter way to deal with events.

The EventArgs class alone is useless since it must be derived to instantiate with any content. This would indicate a subclass should be used, and many already exist in .NET. Sadly, I can't find any good generic ones.
Let's say you want to delegate logging to a generic event... WITHOUT WRITING YOUR OWN EventArgs SUBCLASS. It may seem a pointless exercise, but I like using existing features. You can pass your string through the Object argument, but that goes against it's intended use. Try to find a good reference of EventArgs subclasses on Google, and you'll come up dry. (At least I did.)
ReSharper helps a bit, since when you type "EventArgs" you'll see a list of all classes (within your using/imports scope) that CONTAIN the string "EventArgs". Perusing the list you'll see many classes with no string members. When you get to ControlEventArgs, you see that the Text property might be used, but with all of the overhead of a windows control. ConvertEventArgs might be useful, since you pass the type along with the data, but this still requires tight coupling that's neither well-documented nor inherently type-safe. DataReceivedEventArgs has no implementation. EntryWrittenEventArgs requires an EventLogEntry with a byte array or StreamingContext for data. ErrorEventArgs is closer, with an Exception message, if you don't mind calling all of your log events Exception ErrorEvents internally. FileSystemEventArgs is probably the closest yet, with two strings and a required WatcherChangeTypes enum argument that CAN be set to 0, if you know what you're doing. LabelEditEventArgs uses an int and a string, if you don't mind requiring the Windows.Forms namespace. RenamedEventArgs is similar to FileSystemEventArgs with an extra string. Finally, ResolveEventArgs in System.Runtime.InteropServices passes a single string. There are other libraries, but I stuck to some of the most common ones. So, depending on the implementation I can use ErrorEventArgs, FileSystemEventArgs or ResolveEventArgs for logging.

Related

Testable code: Attach event handler in constructor

as for my understanding, part of writing (unit-)testable code, a constructor should not do real work in constructor and only assigning fields. This worked pretty well so far. But I came across with a problem and I'm not sure what is the best way to solve it. See the code sample below.
class SomeClass
{
private IClassWithEvent classWithEvent;
public SomeClass(IClassWithEvent classWithEvent)
{
this.classWithEvent = classWithEvent;
// (1) attach event handler in ctor.
this.classWithEvent.Event += OnEvent;
}
public void ActivateEventHandling()
{
// (2) attach event handler in method
this.classWithEvent.Event += OnEvent;
}
private void OnEvent(object sender, EventArgs args)
{
}
}
For me option (1) sounds fine, but it the constructor should only assign fields. Option (2) feels a bit "too much".
Any help is appreciated.
A unit test would test SomeClass at most. Therefore you would typically mock classWithEvent. Using some kind of injection for classWithEvent in ctor is fine.
Just as Thomas Weller said wiring is field assignment.
Option 2 is actually bad IMHO. As if you omit a call to ActivateEventHandling you end up with a improperly initialized class and need to transport knowledge of the requirement to call ActivateEventHandling in comments or somehow else, which make the class harder to use and probably results in a class-usage that was not even tested by you, as you have called ActivateEventHandling and tested it but an uninformed user omitting the activation didn't, and you have certainly not tested your class when ActivateEventHandling was not called, right? :)
Edit: There may be alternative approaches here which are worth mentioning it
Depending on the paradigm it may be wise to avoid wiring events in the class at all. I need to relativize my comment on Stephen Byrne's answer.
Wiring can be regarded as context knowledge. The single responsibility principle says a class should do only one task. Furthermore a class can be used more versatile if it does not have a dependency to something else. A very loosely coupled system would provide many classes witch have events and handlers and do not know other classes.
The environment is then responsible for wiring all the classes together to connect events properly with handlers.
The environment would create the context in which the classes interact with each-other in a meaningful way.
A class in this case does therefore not know to whom it will be bound and it actually does not care. If it requires a value, it asks for it, whom it asks should be unknown to it. In that case there wouldn't even be an interface injected into the ctor to avoid a dependency. This concept is similar to neurons in a brain as they also emit messages to the environment and expect answer not knowing neighbouring neurons.
However I regard a dependency to an interface, if it is injected by some means of a dependency injection container just another paradigm and not less wrong.
The non trivial task of the environment to wire up all classes on start may lead to runtime errors (which are mitigated by a very good test coverage of functional and integration tests, which may be a hard task for large projects) and it gets very annoying if you need to wire dozens of classes and probably hundreds of events on startup manually.
While I agree that wiring in an environment and not in the class itself can be nice, it is not practical for large scale code.
Ralf Westphal (one of the founders of the clean code developer initiative (sorry german only)) has written a software that performs the wiring automatically in a concept called "event based components" (not necessarily coined by himself). It uses naming conventions and signature matching with reflection to bind events and handlers together.
Wiring events is field assignment (because delegates are nothing but simple reference variables that point to methods).
So option(1) is fine.
The point of constructor is not to "assign fields". It is to establish invariants of your object, i. e. something that never changes during its lifetime.
So if in other methods of class you depend on being always subscribed to some object, you'd better do it in the constructor.
On the other hand, if subscriptions come and go (probably not the case here), you can move this code to another method.
The single responsibility principle dictates that that wiring should be avoided. Your class should not care how, or where from it receives data. It would make sense to rename OnEvent method to something more meaningful, and make it public.
Then some other class (bootstrapper, configurator, whatever) should be responsible for the wiring. Your class should only be responsible for what happens when a new data come's in.
Pseudo code:
public interface IEventProvider //your IClassWithEvent
{
Event MyEvent...
}
public class EventResponder : IEventResponder
{
public void OnEvent(object sender, EventArgs args){...}
}
public class Boostrapper
{
public void WireEvent(IEventProvider eventProvider, IEventResponder eventResponder)
{
eventProvider>event += eventResponder.OnEvent;
}
}
Note, the above is pseudo code, and it's only for the purpose to describe the idea.
How your bootstrapper actually is implemented depends on many things. It can be your "main" method, or your global.asax, or whatever you have in place to actually configure and prepare your application.
The idea is, that whatever is responsible to prepare the application to run, should compose it, not the classes themselves, as they should be as single purpose as possible, and should not care too much about how and where they are used.

Code-friendly version of event signature in .NET

Preceding posts:
Event Signature in .NET — Using a Strong Typed 'Sender'?
In a C# event handler, why must the “sender” parameter be an object?
Microsoft's conventions and guidelines force .NET users to use special pattern for creating, raising and handling events in .NET.
Event design guidelines http://msdn.microsoft.com/en-us/library/ms229011.aspx state that
Citation:
The event-handler signature observes the following conventions :
The return type is Void.
The first parameter is named sender
and is of type Object. This is the
object that raised the event.
The second parameter is named e and
is of type EventArgs or a derived
class of EventArgs.This is the
event-specific data.
The method takes exactly two
parameters.
These conventions tell developers that the (following) shorter and more obvious code is evil:
public delegate void ConnectionEventHandler(Server sender, Connection connection);
public partial class Server
{
protected virtual void OnClientConnected(Connection connection)
{
if (ClientConnected != null) ClientConnected(this, connection);
}
public event ConnectionEventHandler ClientConnected;
}
and the (following) longer and less obvious code is good:
public delegate void ConnectionEventHandler(object sender, ConnectionEventArgs e);
public class ConnectionEventArgs : EventArgs
{
public Connection Connection { get; private set; }
public ConnectionEventArgs(Connection connection)
{
this.Connection = connection;
}
}
public partial class Server
{
protected virtual void OnClientConnected(Connection connection)
{
if (ClientConnected != null) ClientConnected(this, new ConnectionEventArgs(connection));
}
public event ConnectionEventHandler ClientConnected;
}
Though these guidelines not state why is it so important to follow these conventions, making developers act like monkeys who don't know why and what are they doing.
IMHO, Microsoft's event signature conventions for .NET are bad for your code because they cause additional zero-efficiency effort to be spent on coding, coding, coding:
Coding "(MyObject)sender" casts (not speaking about 99% of situations that don't require sender at all)
Coding derived "MyEventArgs" for the data to be passed inside event handler.
Coding dereferences (calling "e.MyData" when the data is required instead of just "data")
It's not that hard to do this effort, but practically speaking what are we loosing when not conforming to Microsoft's conventions, except that people take you as an heretic because your act of confrontation to Microsoft's conventions verges on blasphemy :)
Do you agree?
The problems you will have:
When you add another argument, you
will have to change your event
handler signature.
When a programmer first looks at
your code, your event handlers will
not look like event handlers.
Especially the latter can waste you far more time than writing a 5 line class.
Regarding having a strongly-typed sender, I've often wondered that myself.
Regarding the EventArgs, I'd still recommend you use an intermediate EventArgs class because you may want to add event information in the future which you don't currently foresee. If you've used a specific EventArgs class all along, you can simply change the class itself and the code where it gets fired. If you pass the Connection as per your example, you'd have to refactor every event handler.
Edit
Jim Mischel made a good point in his comments. By making the sender an object, we enable the same event method to potentially be reused to handle a variety of events. For example, let's say that a grid needs to update itself if:
the user clicks a "refresh" button, or
the system detects that a new entry has been loaded from the server.
You could then say something like this:
serverBus.EntryReceived += RefreshNeededHandler;
refreshButton.Click += RefreshNeededHandler;
...
public void RefreshNeededHandler(object sender, EventArgs args)
{
...
}
Of course, in practice, I have pretty much never had any call for this kind of reuse, whereas the first thing I tend to to in many, many cases is cast the sender to the object type that I know it has to be. If I want to reuse handlers like this, I think it would be easy enough to make two handlers that both call the same convenience method. For me, an event handler is conceptually supposed to handle a specific type of event on a particular group of objects. So I am not personally convinced that the object sender approach is the best convention.
However, I can imagine cases where this would be extremely handy, like if you want to log every event that gets fired.
The biggest problem I see in not following the convention is that you're going to confuse developers who are used to handling events in the way that the runtime library does. I won't say that the convention is good or bad, but it's certainly not evil. .NET developers know and understand how to work with events that are written in conformance with Microsoft's guidelines. Creating your own event handling mechanism on top of that may be more efficient at runtime and might even lead to code that you think is cleaner. But it's going to be different and you'll end up with two event handling "standards" in your program.
My position is that it's better to use a single less-than-ideal standard (as long as it's not horribly broken) than to have two competing standards.
I used strongly typed events (instead of object as it saves me having to cast), it really isn't that hard to understand, "oh look they've used a type that isn't an object"
As for eventArgs, you should use this in case the object changes as per #StriplingWarrior answer.
I don't understand why devs would get confused over it?

Naming methods that are registered to events

Assume that I have a class that exposes the following event:
public event EventHandler Closing
How should methods that are registered to this event be named? Do you prefer to follow the convention that Visual Studio uses when it assigns names to the methods it generates (aka. +=, Tab, Tab)? For example:
private void TheClass_Closing( object sender, EventArgs e )
Or do you use your own style to name these methods?
I've tried different ways to name these methods (like TheClassClosing, HandleClosing, etc.). But I haven't found a good style to indicate that the intent of a method is to handle a registered event. I personally don't like the style (underscore) that Visual Studio uses to generate method names.
I know that registered event-handling methods are always private and that there is no naming convention like the one for methods that raise events (e.g., OnClosing).
Name it after what the handler actually does.
// event += event handler
saveButton.Click += SaveData();
startButton.Click += StartTheTimer();
The two common options for naming is either after what the method does:
theObject.Closing += SaveResults;
Or alternatively after what the method handles:
theObject.Closing += ClosingHandler;
Which is preferable really depends a bit on context.
In the first case it is immediately clear what the handler is going to do, which makes the code registering the handler more readable... but looking at the handler SaveResults in isolation it is not going to be necessarily obvious when it is going to be called, unless the event arguments have an obvious name (ClosingEventArgs or some such).
In the second case, the registration is more opaque (okay, so what is going to happen when Closing happens?), but on the other hand, looking at the handler implementation it will be obvious what is going on.
I guess the one to choose depends on which of the two you want to be more obvious; the site of the registration, or the implementation of the handler.
Or alternatively, you can go for the unholy combination of both methods:
theObject.Closing += ClosingHandlerSaveResults;
Now both the registration site and the implementation are equally obvious, and neither looks particularly elegant (plus, it probably violates the DRY principle).
For the record I prefer the first naming scheme when theObject is contained in a different scope from the implementation of SaveResults, and the second scheme when I am wiring up handlers to events that are all contained within the same class.
I name my event handlers similarly to those created by Visual Studio (the +,=,tab,tab you mention). I try to keep my naming consistent in my code, and I know that I will be creating handlers with the VS auto-creator at least some of the time.
The underscores don't bother me.
maybe: OnObjectNameEventName, such as
private void OnTheClassClosing(object sender, EventArgs e)
This matches the internal event methods, and with the addition of the object name, it should help differentiate, besides, the method to raise events are essentially internal event handlers
User clicks form, form calls OnClicked, does its thing, then raises the Clicked event, it would only be natural from my point of view.

Is the "sender" in Button_Click(object sender... really the sender?

Ted Faison in a podcast on event-based software design mentioned that "sender" and "self" objects in .NET, C++ and Java event statements such as:
private void Button_Click(object sender, RoutedEventArgs e)
are a misnomer since e.g. in the above example "sender" is not really the object which produced the event but a proxy, since you wouldn't want to couple your applications that tightly.
Did I understand him incorrectly (since when I debug it, "sender" does indeed seem to be the original object).
Or is it that common event patterns in these languages (e.g. a common click handler) are tightly coupled but they should be more decoupled, e.g. in composite applications.
He also mentioned that e.g. you shouldn't make inherit from EventArgs since it leads to an explosion of classes, one per event, which only transport a few variables. Many times in his opinion, you can just send a string for instance. He mentioned that this opinion is the opposite of what Microsoft Patterns and Practices suggests.
Any thoughts on these areas?
In most cases, sender is the Button (or whatever) that raised the event. There are some occasions when this isn't the case - such as a (perhaps lazy) pass-thru event:
class Foo {
private Bar bar;
public Foo(Bar bar) {
this.bar = bar;
}
public event EventHandler SomeEvent {
add {bar.SomeEvent += value;}
remove {bar.SomeEvent -= value;}
}
//...
}
Here, if we subscribe to foo.SomeEvent, we will actually get back the event originated by the Bar instance - so sender won't be foo. But this is arguably because we've implemented Foo.SomeEvent incorrectly.
To be honest, in most cases you don't need to check sender; the main time this is useful is when a number of controls share a handler. You should generally be able to assume the sender is the instance you subscribed to (for the purposes of reference-equality tests).
Re EventArgs - the standard pattern (when creating a new event-type) would recommend you to inherit from this. I don't recommend deviating from this. A minor reason is that it allows you to use EventHandler<T>, but there are other variance reasons too. Besides - sometimes doing what other people expect is reason enough; people expect an EventArgs derived value.
That said - I have done non-standard events before (in MiscUtil's Push LINQ) - but this was already in a very unusual setup, so it didn't feel out of place.
First - the 'sender' will hold a reference to the button you clicked. If you have multiple buttons all hooked to the same event, this is how you see which one of the buttons you hit (if you're not passing something in the event arguments to read this).
Also I do to some extend agree that writing new eventargs inheriting frmo EventArgs can lead to explosion of classes - so use with causion. I like just raising an EventArgs.Empty and then have the code catching the event explicit querying the object that raised the event for the data. What i mean is - once you catch the event, instead of reading the data from the event arguments you go to the object that raised the event and read those of its properties you are interrested in. This makes it easier to just read what you need, but ofcourse - you could find yourself in a situation where those properties changed between the event raised and you reading the properties.

The purpose of delegates [duplicate]

This question already has answers here:
Where do I use delegates? [closed]
(8 answers)
Closed 9 years ago.
Duplicate:
Difference between events and delegates and its respective applications
What are the advantages of delegates?
Where do I use delegates?
I wonder what the purpose of delegates is. I haven't used them that much and can't really think of something.
In my courses, it's written that a delegate is a blue-print for all methods that comply with its signature.
Also, you can add multiple methods to one delegate, and then they'll be executed after eachother in the order they were added. Which is probably only usefull for methods that affect local variables or methodes that don't return any values.
I've read that C# implements Events as delegates, which is documented as being:
//Summary: Represents the method that
will handle an event that has no event
data.
//Parameters:
//sender: The source of the event.
//e: An System.EventArgs that contains no event data.
[Serializable]
[ComVisible(true)]
public delegate void EventHandler(object sender, EventArgs e);
Still, it's kinda confusing. Can someone give a good, usefull example of this concept?
Yeah,
You're almost there. A delegate refers to a method or function to be called. .NET uses the Events to say.. when someones presses this button, I want you to execute this piece of code.
For example, in the use of a GPS application:
public delegate void PositionReceivedEventHandler(double latitude, double longitude);
This says that the method must take two doubles as the inputs, and return void. When we come to defining an event:
public event PositionReceivedEventHandler PositionReceived;
This means that the PositionRecieved event, calls a method with the same definition as the
PositionReceivedEventHandler delegate we defined. So when you do
PositionRecieved += new PositionReceivedEventHandler(method_Name);
The method_Name must match the delegate, so that we know how to execute the method, what parameters it's expecting. If you use a Visual Studio designer to add some events to a button for example, it will all work on a delegate expecting an object and an EventArgs parameter.
Hope that helps some...
As you noted a delegate is a way to create a signature for an method call. There are many great examples of using delegates, but the one that really opened my mind is this example.
public delegate Duck GetDuckDelegate();
public GetDuckDelegate GiveMeTheDuckFactoryMethod(string type)
{
switch(type)
{
case "Rubber":
return new GetDuckDelegate(CreateRubberDuck);
case "Mallard":
return new GetDuckDelegate(CreateMallardDuck);
default:
return new GetDuckDelegate(CreateDefaultDuck);
}
}
public Duck CreateRubberDuck()
{
return new RubberDuck();
}
public Duck CreateMallardDuck()
{
return new MallardDuck();
}
public Duck CreateDefaultDuck()
{
return new Duck();
}
Then to use it
public static void Main() {
var getDuck = GiveMeTheDuckFactoryMethod("Rubber");
var duck = getDuck();
}
Arguably, the Factory pattern would be a better method for this, but I just thought up this example on the fly and thought it proved the point of how delegates can be treated as objects
Delegates allow you to pass methods around like values.
For example, .Net has a method called Array.ForEach that takes a delegate and an array, and calls the delegate on each element of the array.
Therefore, you could write,
int[] arr = new int[] { 1, 2, 4, 8, 16, 32, 64 };
Array.ForEach(arr, new Action<int>(Console.WriteLine));
This code will call Console.WriteLine for each number in the array.
There are many things you can do by making functions that take delegates, especially when combined with anonymous methods. For examples, look at LINQ.
Many people initially get confused with the real need for delegates and events. I was one of them and it took me some time to figure it out :-). Recently answered a similar query in ASP.NET forums and thought it would be good if I create a blog post on this topic! Here was the query:
"I was reading an example somewhere of a Bank Class that if the minimum balance is reached you need to inform the rest of the app that the min has reached, but can't we do that by just calling a normal method.
for example: lets say when we deduct some amount from the balance and if minimum reached then call some method to take some action, I am totally missing why do we need delegates and custom events here?"
Thing is in the Bank case, you can definitely call a method, but then it would be simple procedural programming, we need event based programming when we want our code to respond to some events generated by a system.
For eg.: think that windows OS is a system, and we are writing a code (in any language) where we want to capture an event like mouse_click(). Now how would our program know that a mouse click has occured? We can use low level code for it, but since OS is already handling low level code, its best to capture an event raised by the OS.
In other terms, the moment a mouse_click() happens the OS fires an event. The OS doesnt care who captures this event and uses it, it just sends out a notification. Then any code (like ours) can capture that event and use it accordingly. This saves us a lot of time to write code for the same ourselves. And other programs too can use the same event and handle it accordingly.
Similarly, the banking system can be huge, and many other outside applications might be accessing it. The banking system does not know how many such applications there are which need it, or are dependent on it, and how would they handle certain situations like when balance is low, so it simply fires an event whenever low balance occurs, and this event can be used by any other code, besides banking code itself.
Note that each susbcriber to that event can handle that event independently, for eg. the banking code might stop something from executing if balance is low, some other reporting app might send an email in such a case, or some ATM code can stop a particualr transaction and notify the user that balance is low.
Hope this clears things a bit!
I can provide you with an example using a web application architecture:
Generally, with a web application you can provide a front controller that receives requests from many clients. We could put all our methods within the front controller for dealing with the many different types of requests from the clients. However, this get a little cumbersome. Instead we can use delegates to encapsulate functionality for different requests. We could have:
Authentication Delegate
User Management Delegate
and so on. So it's a neat way to split up functionality into logical chunks - delegates. The Struts framework is based on this way of working (the ActionServlet and Action classes).
There are lots of excellent articles explaining delegates - here are some good ones:
Delegates and events
C# Delegates Explained
Delegates in C#
Delegates, to my understanding, provides a way of specializing the behavior of a class without subclassing it.
Some classes have complex generic behavior, but are still meant to be specialized. Think of a Window class in a GUI framework: A Window can propably do a lot on it's own, but you would most likely still want to specialize it in some way. In some frameworks, this is done via inheritance. A different way of doing it is with delegates. Say you want something to happen when the Window resizes: Your delegate class can then implement a method called onWindowResize (provided of course that the Window class supports this), which gets called whenever the Window resizes and is responsible for any specialized behavior when the Window resizes.
I'm not going to argue the merits of delegation over inheritance, but suffice it to say that there are many who feel that delegation is "cleaner" than inheritance.

Categories

Resources