This seems odd to me -- VB.NET handles the null check implicitly via its RaiseEvent
keyword. It seems to raise the amount of boilerplate around events considerably and I don't see what benefit it provides.
I'm sure the language designers had a good reason to do this.. but I'm curious if anyone knows why.
we usually work around this by declaring our events like this:
this has two advantages. The first is that we don't have check for null. The second is that we avoid the critical section issue that is omnipresent in typical event firing:
But with the automatic initialization of Foo to an empty delegate, there is never any checking necessary and the code is automatically thread-safe, and easier to read to boot:
With apologies to Pat Morita in the Karate Kid, "Best way to avoid null is not have one."
As to the why, C# doesn't coddle you as much as VB. Although the event keyword hides most of the implementation details of multicast delegates, it does give you finer control than VB.
Note that as of C# 6, the language now provides a concise syntax to perform this null check conveniently. E.g.:
See Null Conditional Operator
Because RaiseEvent carries a some overhead.
There's always a tradeoff between control and ease of use.
Extension methods provide a very cool way, to get around this. Consider the following code:
Now you can simply do this:
However as others already mentioned, you should be aware of the possible race condition in multi-threaded scenarios.
Edit: As the OP points out, this answer does not address the body of the question. However, some may find it useful because it does provide an answer for the title of the question (when taken by itself):
It also provides context for the intent of the body of the question which some may find useful. So, for those reasons and this advice on Meta, I'll let this answer stand.
Original Text:
In its MSDN article How to: Publish Events that Conform to .NET Framework Guidelines (C# Programming Guide) ( Visual Studio 2013), Microsoft includes the following comment in its example:
Here is a larger excerpt from Microsoft's example code that gives context to that comment.
It's certainly a point of annoyance.
When you write code which accesses a field-like event within a class, you're actually accessing the field itself (modulo a few changes in C# 4; let's not go there for the moment).
So, options would be:
Handle all delegate invocations differently, such that:
wouldn't throw an exception.
Of course, for non-void delegates (and events) both options raise a problem:
Should that silently return 0? (The default value of an
int
.) Or is it actually masking a bug (more likely). It would be somewhat inconsistent to make it silently ignore the fact that you're trying to invoke a null delegate. It would be even odder in this case, which doesn't use C#'s syntactic sugar:Basically things become tricky and inconsistent with the rest of the language almost whatever you do. I don't like it either, but I'm not sure what a practical but consistent solution might be...