Mandating and enforcing culture
Update in response to Eric Lippert's blog posts: So there's a major thing I'd missed about event handlers: "event handlers are required to be robust in the face of being called even after the event has been unsubscribed", and obviously therefore we only need to care about the possibility of the event delegate being And so: "There are other ways to solve this problem; for example, initializing the handler to have an empty action that is never removed.But doing a null check is the standard pattern." So the one remaining fragment of my question is, to be added to the event declaration, and this eliminates those little piles of stinky ceremony from every place where the event is raised.It also doesn't guarantee that you always "see" the latest value of the variable.(Note that UI controls often have a large number of events, most of which are never subscribed to.It would be easy to make sure that the empty delegate is cheap to instantiate. Surely it must be that (as Jon Skeet suggested) this is just .NET 1.x advice that hasn't died out, as it should have done in 2005?: I thought from reading about optimizations that this might also require the event member to be volatile, but Jon Skeet states in his answer that the CLR doesn't optimize away the copy.But meanwhile, in order for this issue to even occur, another thread must have done something like this: // Copy the event delegate before checking/calling Event Handler copy = The Event; // Better delist from event - don't want our handler called from now on: other Object. Empty); // Call any handlers on the copied list runs after the author has unsubscribed, and yet they just unsubscribed specifically to avoid that happening.
Conclusion, Are not modern day languages supposed to solve problems like these for us?So I contend that merely doing this copy/check idiom is cargo cult programming, adding mess and noise to your code.To actually protect against other threads requires a lot more work.Consequently, people who are not taking that additional care might as well ignore this advice - it simply isn't an issue for single-threaded programs, and in fact, given the absence of In case it wasn't clear, I did grasp the intention of the advice - to avoid a null reference exception under all circumstances.My point is that this particular null reference exception can only occur if another thread is delisting from the event, and the only reason for doing that is to ensure that no further calls will be received via that event, which clearly is NOT achieved by this technique.
(I checked it with either Joe Duffy or Vance Morrison a while ago; I can't remember which.) Without the volatile modifier it's possible that the local copy taken will be out of date, but that's all.