Is the "sender" in Button_Click(object sender... really the sender? - c#

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.

Related

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?

Is it poor form for a C# class to subscribe to its own published events?

I'm probably just being neurotic, but I regularly find myself in situations in which I have class that publishes an event, and I find it convenient to subscribe to this event from within the class itself (e.g. in the constructor), rather than only subscribing from external classes.
This sounds reasonable to me, but I can't help the nagging feeling that it's a poor practice, for the simple reason that I'm always faced with the question: "Why not perform the actions that you'd provide in the event handler in the code which fires the event?"
public class Button
{
public Button()
{
this.Click += someHandler; // bad practice?
}
public event EventHandler Click;
public void HandleInput()
{
if (someInputCondition)
{
// Perform necessary actions here rather than
// subscribing in the constructor?
this.Click(this, ...);
}
}
}
Are there any drawbacks to subscribing to your own events?
This sounds reasonable to me, but I can't help the nagging feeling that it's a poor practice, for the simple reason that I'm always faced with the question: "Why not perform the actions that you'd provide in the event handler in the code which fires the event?"
To answer that question, consider partial class scenarios. Suppose you have a base type B. You run an automated tool that decorates B by extending it to derived class D. Your tool generates a partial class so that developers consuming D can further customize it for their own purposes.
In that case, it seems perfectly reasonable that the user-authored side of D would want to sign up to be called when events declared by B or the machine-generated side of D are raised by the machine-generated side of D.
That was the scenario we found ourselves in when designing VSTO many years ago. As it turns out, it was not difficult to do this in C# but it was quite tricky to get it all working in VB. I believe VB has made some tweaks to their event subscription model to make this easier.
That said: if you can avoid this, I would. If you're just making an event for internal subscription that seems like a bad code smell. Partial methods in C# 3 help out greatly here, since they make it easy and low-cost for the machine-generated side to call little notification functions in the user-generated side, without having to go to the trouble of publishing an event.
I see no problem with this. But if you handle the events in the same class you could also override the event method:
protected override void OnClick(Eventargs e)
{
base.OnClick(e);
}
This is more efficient and gives you the power to swallow the event if necessary (simply not calling base.OnClick()).
There's a very exotic problem due to internal optimization when doing this. Due to the optimization adding/removing event handlers is not thread safe. It only applies to events that are used by the declaring type like in your example.
Fortunately this has been changed with 4.0, but if you're on previous version, you could experience this.
The issue is that “someHandler” will change the state of your object. Do you want this state changing before or after any “external” code is run by the event?
It is not clear at what point the state change will be make if you subscribe to the event, however calling it in “HandleInput()” make it a lot clearer when it will be called.
(Also it is more normal to call “HandleInput()”, “OnClick” and make it virtual so sub classes can override it)
After saying the above, normally there is no great harm in subscribing to your own event; in UI classes that represent forms it is very common, otherwise it tend to “surprise” a lot of people that read your code.
If your button class should be the first which receives the click event, you should write your code in the event method, eg.:
protected virtual void OnClick(EventArgs e)
{
//insert your code here
if(this.Click != null)
{
this.Click(this, e);
}
}
but if it's not necessary that your class is the first reciever, you can subscribe to the event normally.
if you take the ordinary System.Windows.Form class as an example,
when you want to handle the Form_Load event (using visual studio designer), it is handled
in the class of the Form itself !
this.Load += new System.EventHandler(this.Form1_Load);
private void Form1_Load(object sender, EventArgs e)
{
}
so i think it is not a problem at all !!.

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.

What use cases exist for non-static private or protected events?

What purpose do protected or private (non-static) events in .NET really serve?
It seems like any private or protected event is more easily handled via a virtual method. I can (somewhat) see the need for this in static events, but not for normal events.
Have you had a use case before that clearly demonstrates a need or advantage for a non-static protected or private event?
Here's a slightly bizarre but real-world scenario I implemented once. You have machine-generated and user-generated halves of a partial class. The machine-generated half contains code which wishes to inform the user-generated half when some event occurs. But the user-generated half might not care to do anything, or it might care to do rather a lot. It seems rude of the machine-generated half to require that the user-generated half implement a particular method in order to handle a message they don't have any interest in listening to.
To solve this problem, the machine-generated half could fire on a private event. If the user-generated half cares, it can subscribe the event. If not, it can ignore it.
This scenario is now addressed more elegantly by partial methods in C# 3, but that was not an option back in the day.
Seems to me that a good example of where a private event is useful is in component/control building, often you may have a component that is a composite of 1 or more other components, private events that contained components can subscribe to is a handy and easy implementation of an observer pattern.
Edit:
Let me give an example...
Say you are writing a Grid type control, and inside of this control you would most likely have a bunch of contained classes that are created dynamically Rows, Cols, headers etc for example, say you want to notify these contained classes that something they care about has happend, say a Skinning change or something like that, something that you don't necesarrily want to expose as an event to the grid users, this is where private events are handy, simply have one or 2 handlers and as you create each instance of your row or col or whatever attach the handler, as otherwise you just have to write your own observer mechanism, not hard, but why when you dont have to and you can just use multicast events.
Nested types have access to the enclosing type's private and protected events. I've used this feature to notify child controls (the nested type) of state changes in the parent control (the enclosing type) in a Silverlight application.
Sorry to drag up an old thread, but I use private events with impunity in one of my projects, and personally, I find it's a good way of solving a design issue:
Here's the abbreviated code:
public class MyClass
{
private event EventHandler _myEvent;
public ExternalObject { get; set; }
public event EventHandler MyEvent
{
add
{
if (_myEvent.GetInvocationList().Length == 0 && value != null)
ExternalObject.ExternalEvent += HandleEvent;
_myEvent+= value;
}
remove
{
_myEvent-= value;
if (_myEvent.GetInvocationList().Length == 0)
ExternalObject.ExternalEvent -= HandleEvent;
}
}
private void HandleEvent(object sender, EventArgs e)
{
_myEvent.Raise(this, EventArgs.Empty); // raises the event.
}
}
Basically, MyEvent is only ever raised in the event handler of ExternalObject.ExternalEvent, so if there's no handlers for MyEvent then I don't need to attach a handler to the external event, speeding up the code slightly by saving a stack frame.
Not only the current instance can access a private member. Other instances of the same type can too! This enables some scenarios where this access control may be useful.
I am thinking of a tree structure where all nodes inherit a certain type and a private/protected event allows to propagate leaf events to their parents. Since they are the same type, the parent can register to the child's private event. Yet any client of the tree structure cannot.
I can definitely see a use case in a directory like storage system where where each directory needs to propagate its last modified date to its parent for example.

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

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.

Categories

Resources