One thing that I find slightly annoying is having to null-check events. An event that has no subscribers is going to be null, so often times code like this has to be written:
MyEvent?.Invoke()
One solution for this problem I've found was this initialization pattern, where we initialize event with a no-op delegate:
public event Action MyEvent = delegate { };
Now, since this event is always going to have at least one dummy subscriber, we no longer have to check for null:
MyEvent.Invoke()
While this is pretty convenient, I was wondering whether this pattern a good practice, or is there some reason that I don't see that would make this a bad decision (aside from having to call an extra dummy subscriber, but I am fine with that)? Thanks.
Related
This situation seem very interesting to me.
In C# you need to check if there is any listener to the event in a class before firing it.
Assuming event structure of C# is a non-standart(Meaning Microsoft did it) implementation of Observer observable pattern for ease of use.
Why didn't they implement this inside that structure? Is there solid reasons or documentation for this choice.
Is it a necessity do null checking, or am I wrong in my assumption for event structures needing null checks under all circumstances.
This is a more of a curiosity question looking for an answer to this implementation choice by microsoft. Which I hope will lead to further understanding of delegate and event keyword inner workings.
Yes, you must do the null check.
Calling a delegate that is null results in a NullReferenceException.
You might be tempted to intialize all delegates with a non-null, empty event handler. However, that would be far worse than testing for null, in terms of CPU usage, memory usage, and lines of code.
There's a reply to this question in a blog by Eric Gunnerson.
Basically it seems to say that Microsoft thought about changing it, but it would break existing code.
In other words, it was a mistake in the original design for events, but it's too late to fix it.
You can add a default event listener, thus avoiding the null check
public Action<object, EventArgs> SomeEvent = (o, e) => { };
in that way, you can call SomeEvent without checking for null, since it contains a default (empty implementation) listener. Please note that it might hurt performance.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is there a downside to adding an anonymous empty delegate on event declaration?
The following pattern is quite common when using event handlers (in C#):
public event Action handler;
…
// some method:
if(handler != null) handler();
Are there any downsides of assigning an empty delegate to this event? This would save the if !=null condition everywhere, where the event is fired. Of course, this only applies, when the we cannot guarantee that the event is always assigned a proper delegate.
public event Action handler;
…
// in constructor:
handler += ()=>{};
…
// some method:
handler();
Sure, there's a slight performance hit, but it makes the code much cleaner. What's the best practice in such a case? Any technical disadvantages?
Interesting idea, I've never thought of doing that. The way i do my custom events is i make a OnCustomEventName taking parameters for the event and just do the check in there for null. and call OnCustomEventName from the code wherever i want the event triggered from.
Avoids any performance hits and keeps the operational code cleaner than a 2-line if check every time you want the event fired.
That being said this isn't answering the question about technical disadvantages but more of a best practice when firing events.
example code for threadsafe "On" function.
private void OnCustomEventName()
{
DelegateName localhandler = CustomEventName;
if (localhandler != null)
localhandler();
}
Instead of adding an empty delegate in the constructor, you can wrap the handler in a function which first checks if the handler is null then calls it. The downside of this is if you have a lot of events, you will have a lot of functions that wrap each event.
private void HandlerWrapper()
{
Action localHandler = handler;
if (localHandler != null) handler();
}
I haven't really found any big downsides to do this and generally I prefer it over checking for null. The only issue I cant think of is that it might lead to annoying steps in the code when debugging (i.e.
having to step over the empty delegate whenever stepping into an event).
I think that performance isn't an issue - if application performance degenerates significantly by invoking events, the event should probably not have been there in the first place.
From the content of the answer to this question I learned a new trick; to add a trivial handler to an event in order to avoid null checking when it is raised.
public static event EventHandler SomeEvent = delegate {};
and to invoke it without the null checking:
SomeEvent(null,EventArgs.Empty);
Does this add significant overhead? If not, why isn't something like this built in?
Does this add significant overhead? If not, why isn't something like this built in?
It doesn't add significant overhead - merely a delegate call when the event is raised.
As for why it's not built-in - there are a couple of downsides:
This isn't necessarily bullet proof - you can still clear the handler list afterwards, in which case, you'd still need the proper checking.
This does add overhead - while minor, that overhead could be problematic in specific scenarios.
I have seen some people leaning on handing methods to callbacks/events and then sometimes just handing them lambdas.
Can anybody speak to any difference between the two? I would have originally thought them to be the same, but the inconsistency I have seen implemented sometimes makes me wonder if there is a case where one is preferable over the other? Obviously if there is a very large ammount of code it shouldn't be an on the spot lambda, but otherwise..
Can you all outline any differences between the two if any, and outline the rules you use in choosing between the two when both are available?
One of the biggest differences between the two is the ease by which you can unsubscribe from the event. With the method based approach unsubscribing is a simple operation, simply use the original method
m_button.Click += OnButtonClick;
...
m_button.Click -= OnButtonClick;
With lambdas this is not as simple. You must store away the lambda expression and to be used later on to unsbuscribe from the event
m_button.Click += delegate { Console.Write("here"); }
...
// Fail
m_button.Click -= delegate { Console.Write("here"); }
EventHandler del = delegate { Console.Write("here"); }
m_button.Click += del;
...
m_button.Click -= del;
It really detracts from the convenience of using lambda expressions.
In most languages that have lambdas (including C#), creating a lambda inside a method creates a closure -- that is, the local variables inside the declaring method will be visible to the lambda. That's the biggest difference i'm aware of.
Aside from that, unless you name your event handler somehow, in a way that's accessible in another function, you'll find it hard to detach the event handler later. This is doable by storing the delegate in an instance- or class-level variable, but it can be kinda ugly.
The biggest reason for using a Lambda is to have delayed execution, i.e. you define the operations you want to perform, but you won't have the parameters until later. You generally don't use lambdas for events and callbacks; you use anonymous methods.
Using anonymous methods for events and callbacks is okay for simple events that you don't need to unsubscribe to. The biggest determining factor for me is where I'm declaring it. I'm not going to declare an event handler for a form as an anonymous method, but if I have a short-lived need to connect to an event, it might be okay.
In general, I use actual methods for callbacks and events more than anonymous methods; the events I'm handling are tied to the lifetime of the object, not the lifetime of the method, and I find that it's clearer in code to have callbacks clearly defined external to the function that hooks them up. Some of that is personal preference.
In most cases, there is little practical difference. Which one to use is mainly a matter of personal preference (i.e. what you want the code to look like). In some cases, there are some practical reasons to prefer one over the other:
As noted in the accepted answer, unsubscribing an anonymous method is more complex than unsubscribing a named method. Without a name, there's no way to refer to the anonymous method except by the delegate instance created at runtime where the anonymous method is declared. Using a named method, the delegate can be unsubscribed without having retained a reference to the original delegate (or its equivalent).
On the other hand, a reason to prefer a lambda expression is when the handler for the event is an implementation detail unique to the named method in which the lambda/anonymous method is declared. This can help keep such implementation details private and local to the method where they are used.
Another reason one might use a lambda expression is if there's a need to "adapt" the delegate type. I.e. you do want to call a named method to handle the event, but that method has a different signature than that required by the event. This might be the case where you want to reuse the method for different events or other situations, where some of the parameters from the event might not be applicable. Another case might be where you want to introduce a new parameter a value for which the event might not provide (e.g. an index for a collection of objects all having the same event you want to subscribe to).
There is one special case that may sometimes come up, which is the choice of whether to use a named method by itself, or to use an anonymous method that then calls that named method. It is important to note that, in absence of other practical reasons for choosing one over the other, using a named method is marginally more efficient in this particular case, because it removes one method call from the invocation. In practice, you'll probably never notice the difference, but it's just overhead so if there's no specific, practical reason to incur it, one should probably avoid it, i.e. subscribe the named method directly.
A few years ago, I read a book that described how you could override the default event 'dispatcher' implementation in .NET with your own processor.
class foo {
public event EventHandler myEvent;
...
}
...
myFoo.myEvent += myBar1.EventHandler;
myFoo.myEvent += myBar2.EventHandler;
Whenever the event fires, both myBar1 and myBar2 handlers will be called.
As I recall, the default implementation of this loop uses a linked list and simply iterates over the list and calls the EventHandler delegates in order.
My question is two fold:
Does someone know which book I was reading?
Why would you want to override the default implementation (which might be answered in the book)?
Edit: The book I was referring to was indeed Jeffrey Richter's CLR via C#
It could have been one of many books or web articles.
There are various reasons why you might want to change how events are subscribed/unsubscribed:
If you have many events, many of which may well not be subscribed to, you may want to use EventHandlerList to lower your memory usage
You may wish to log subscription/unsubscription
You may wish to use a weak reference to avoid the subscriber's lifetime from being tied to yours
You may wish to change the locking associated with subscription/unsubscription
I'm sure there are more - those are off the top of my head :)
EDIT: Also note that there's a difference between having a custom way of handling subscription/unsubscription and having a custom way of raising the event (which may call GetInvocationList and guarantee that all handlers are called, regardless of exceptions, for example).
I seem to remember something similar in Jeffrey Richter's CLR via C#. Edit: I definitely do remember that he goes into detail about it.
There are a few different reasons for taking control of event registration. One of them is to reduce code bloat when you've got TONS of events. I think Jeffrey went into this in detail within the book...
No
You might, for example, need to break the call chain based on the result of one of the handlers. Say your CustomEventArgs object has a property 'Blocked', which when set to true suppresses all further event handler invocations.