Why should derived classes handle an event without attaching a delegate? - c#

Q1:
“The ListControl.OnSelectedIndexChanged method also allows derived classes to handle the event without attaching a delegate. This is the preferred technique for handling the event in a derived class.”
A) If I understand the above quote, then if we derive a class from ListControl, we should instead of subscribing to SelectedIndexChanged event, treat OnSelectedIndexChanged() method as an event handler and thus put any event processing logic inside it:
protected override void OnSelectedIndexChanged(
EventArgs e
{
//event handling logic
}
Why would that be better than subscribing to an event(inside .aspx) via OnSelectedIndexChanged = ”name_of_event_handler”?
B)
Anyways, in ascx file we use OnSelectedIndexChanged attribute to attach event handler to an event. Name of this attribute is the same as the name of OnSelectedIndexChanged() method. Why is that? Why isn't instead the name of this attribute SelectedIndexChanged:
<asp:ListControl SelectedIndexChanged = ”name_of_event_handler”
Afterall, attribute refers to an event and not to a method ( OnSelectedIndexChanged() ) that calls this event!
thanx
EDIT:
Hello,
HOWEVER, be sure that you call base.On[EventName] or the event won't fire!
Assuming you don’t want anyone else to be able to respond to this event, then would it be perfectly OK not to call base.On[EventName], since I would think not calling it won’t really do any harm besides not firing an event ( and thus event handlers won't be called )?
I realize some events need to be fired in order for Framework to do its job, but what about not calling base.On[SelectedIndexChanged]?

It is "better" in that:
it is cheaper to use virtual (inheritance) where possible - it removes the need for a few extra objects (delegate instances, etc)
it allows the overriding code to know where it comes in the sequence - i.e. if multiple callers are listening, does it fire first? second? in the middle?
The first point is arguably more important for efficiency, especially in things like controls that have sparse event handlers (i.e. things like EventHandlerList instead of a field-like-event).
I don't really understand the second question, but at a guess: convention.

In general, I prefer to override the On[EventName] functions so that I can control if my logic happens before or after the logic in any subscribers.
HOWEVER, be sure that you call base.On[EventName] or the event won't fire!

Related

what if I need to execute event handlers in certain order?

I have event, for example like that:
public event EventHandler<NewReadyMessageEventArgs> NewReadyMessage
The problem is that i need to attach two handlers to it and i need to execute one before another (because the last one depends on first one). I.e. I need certain order of handlers execution.
I understand that in reality handlers will be executed one by one and so I just need to attach them in right order but that would be very error-phrone design.
I want to create separate handler and attach it. In this handler I just want to execute my two handlers in right order. What do you think and what would you suggest?
The problem is that i need to attach two handlers to it and i need to execute one before another (because the last one depends on first one)
In this case, I would rethink your design. It likely makes more sense for the "first" handler to raise its own event.
The second handler could attach to that event, and have the results of both items.
I would not rely on the internal implementation to ensure that the handlers get called in a specific order.
If the handlers can't know about each other but you need them to run in a certain order I would create a "parent" handler that calls the other two handlers in the correct order.
I would suggest implementing your own add implementation if you don't want the default multicast delegate with the default event add/remove implementation.
For more information see http://msdn.microsoft.com/en-us/library/cc713648.aspx
In case it wasn't obvious, if you don't use the default multicast delegate, invocation of subscribers needs to be implemented manually. The above link details how to write custom add/remove to use a multicast delegate. This answer assumes you don't use a multicast delegate For example, something like:
private List<EventHandler> eventList = new List<EventHandler>();
public event EventHandler Event1
{
add { eventList.Add(value); }
remove { eventList.Remove(value); }
}
private void RaiseEvent1()
{
foreach(var e in eventList)
{
e(this, EventArgs.Empty);
}
}
Use a SortedList if you want a specific order...
It sounds like this might be a place where you just need to have multiple (2) events.
If the order is important have two events, and have one that is simply fired right after the other. You can see this at, for example, the page lifecycle in ASP. There are lots of events, and in some cases they're all fired one after the other with thing really inbetween them other than a guarantee that all handlers of the previous event are run. That sounds just like your case here.

How to find out if an event has fired in another event handler without the use of flags?

I have two events A and B.
I need to check in the event handler of B if the Event A was raised. I know I can do it using a flag but I have used so many flags so far for these kind of situations; and want to use an alternate strategy.
To me this sounds like bad design. If event of A was raised, it should have done something like modifying the state of some object instance. So if event of B is raised, by checking the state changes done by event of A, you should know if it was raised or not. If I am wrong in terms of bad design, then please post more information on your solution.
Example:
void eventOfA(EventArgs args)
{
// modify application or whatever state like
myAppContext.ChangeStatus(2);
// or
myWhateverInstance.DoStuff();
}
void eventOfB(EventArgs args)
{
if(myAppContext.Status == 2)
// eventOfA was raised
else
// eventOfA was not raised
// or
if(myWhateverInstance.DidStuff)
// eventOfA was raised
else
// eventOfA was not raised
}
Maybe you should reconsider the semantic of your events, and create another one.
Say if you have MyApplicationExit and SaveMyData Events, and that you don't need to save everything when application will exit right after, you can indeed check in the SaveMyData Handler wether MyApplicationExit was called before. But a much better choice would be to create another SaveMyDataOnExit event that you send when you are exiting and user want things to be saved. No so much work added since you HAVE to differentiate each case.
All that booleans you need are for Events ? Because if the event handling of .Net doesn't fit you, you might also consider to write your own EventHandler for your custom events, defining the meaning of AddHandler, RemoveHandler and RaiseEvent. So you might create any complex relationship beetwenn events, like raising one event could automatically -or with a condition on the event arg- raise another event, or whatever suits better your needs.

Store a list of EventHandlers to unsubscribe from

I have a class with a method, Register that subscribes to a number of events on classes that it contains, using the standard aClass.SomeEvent += the_handler. This class also has an Unregister method that unsubscribes from these events using -=. This works just fine but we're finding that if we add a new event to subscribe to that it's very easy to forget to include the unsubscription in Unregister. This manual method of maintaining event subscriptions is proving to be fragile.
Is there a way to maintain a list of subscriptions that can be iterated over and unsubscribed from dynamically? (And potentially iterate over and re-subscribe when calling Register after Unregister).
Some details: The class has a reference to 3 other classes (currently, but not definitively limited to 3), the various events on these classes are all of type EventHandler or EventHandler<T>.
how about getting invocation list from the EventHandler.GetInvocationList() and then ierate through and manually remove/unregister them ? note, you only have access to the GetInvationList() method from the class that has that EventHandler, so you might need to expose a method UnregisterAll() to make sure it removes all the delagates in the event invocation list
you can also make sure your class inherits IDisposable and with using(){ } it will call Dispose which will clean up all subscribers
After a thorough look through SO I found this answer:
C# Dynamic Event Subscription
That does what I want (almost). I don't like having to name events using strings as and such I won't be pursuing this design any further. Even though it's not the design I want, the answer shows a very useful method to achieve the desired behaviour and as such I'm marking this as accepted.

C# Best Practice - Event subscription

Very basic question, so I'm just looking for a best practice to follow.
My class has a few events which should be subscribed to. (e.g. DiscoveryCompleted). Within the method I do check if the event is null or not, however I'm not sure if I should raise an exception, if so what type. NotImpletementedException?
If the exception is unhandled it doesnt look very elegant.
Your thoughts?
My thought is this is precisely what the NotImplementedException was created for. You should never encounter a NotImplementedException in production code, but it makes it painfully clear during testing that you have a code path that has, well, not been implemented.
Kinda like a TODO comment, but more in-your-face :)
Although, I might question whether having an event handler that must be subscribed to, and not having a default subscriber, doesn't indicate a design issue.
EDIT
I think I misunderstood your initial question slightly, based on your comment. As others have stated (and I questioned), you should not be throwing an exception when you don't have a subscriber to an event handler; simply don't try to call it. If no one cares that event x happened, you can't really do anything about that.
It's not your code's responsibility to care whether anyone cares that it happened, but simply to notify them that it happened if they do care.
EDIT 2 - now with more code
public interface INeedToKnowAboutSomethingImportant
{
void WhenSomethingImportantHappens(SomethingImportantHappenedEventArgs args);
}
public class DoesSomethingImportant
{
private readonly INeedToKnowAboutSomethingImportant _needyDependency;
public DoesSomethingImportant(INeedToKnowAboutSomethingImportant needyDependency)
{
_needyDependency = needyDependency;
}
protected void SomethingImportantHappened(object sender, EventArgs e)
{
//Handle internally
_needyDependency.WhenSomethingImportantHappens(new SomethingImportantHappenedEventArgs(e));
}
}
Following this pattern, you don't have to worry about whether anyone is subscribed to your event handlers. You have to fulfill the dependency, but it doesn't matter AT ALL what you fill it with because whatever it is, it will have that method for you to call.
Events should be optionally subscribed to.
If your class has to call a method, pass a delegate on its constructor instead.
You should not throw NotImplementedException when you check your event. Just check, and execute if not null.
Take for instance. You put an element on your page, but you do not intend to implement any events on the button. The button check for Click event, don't find one, and throws NotImplementedException.
Now that is just wrong.
Event is something that's raised when a certain point the program is hit. Then you can have code that is "triggered" by it. The main path of the code should not be affected whether an event is present or not. If the main path of your code cannot continue without the event being triggered, then you need to use a Method instead.
My suggestion is:
1) Create an event.
2) Subscribe the event with handlers that you are going to implement later.
3) Throw the NotImplementedException in the handler.
As for exception is unhandled, you should never be handling NotImplementedException anyway :P... (And you shouldn't be throwing NotImplementedException for null reference to events).
You should not worry about the event object being null. If no one has subscribed to the event then nothing. If you need another function to run outside of your event raising class, then you need to use another pattern besides the observer pattern. As Eduardo suggested you can pass in a delegate, you might also consider a builder pattern.
I would not throw if an event has no subscribers.
In the "On" method that raises the event you will need a null test (note the race condition prevention). Elsewhere your class should not assume that the event has subscribers.

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.

Categories

Resources