Okay, that's fine for an event on a simple, transient instance of an object. But what if, in the lifecycle of our application, we could potentially throw away hundered of EventHandlers? And what if, further complicating the problem, the event is static? It sure would be nice if we could actually remove the EventHandler, once it has been raised.

Well, we can. There are two ways to achieve this: one is simple but requires duplication for reuse; the other is complicated but easily reusable.

Since we know the type of TestClass's SimpleEvent, we can declare a strongly typed EventHandler and assign an anonymous method to it. Not knowing this type at compile-time is the source of much of the complication of the reusable solution below.

Also, we temporarily assign null to handler before referring to handler within the body of the anonymous method to avoid the noted compiler error. Then, we assign the anonymous method to handler before attaching handler to the event.

But, Jacob, this works fine. Why would we care about "improving" it?

Well, for starters, it's not very extensible. The critical code is embedded into the anonymous method. So anytime we want to bring different functionality to this event, we'll need to repeat this pattern. Also, not only is the critical code not pluggable, but we've constrained ourselves to only EventHandler events. There are other types of strongly typed event handling delegates with far more interesting EventArgs (and how does the name "EventArgs" not violate the Framework Design Guidelines, anyway?). And lastly, … well… because we can:

[At this point in the post, the author suddenly switches voices: the hand-holdy, instructive teacher is replaced with the programmer who has spent too much time with the material at hand and pastes in swaths of code assuming his audience will understand. Apologies for the lack of exposition to follow.]

Note that the second type argument is the type of the EventArgs, not the type of the EventHandler delegate itself. This is due to the inablity to apply a Delegate constraint on a type argument, coupled with the need to assign an anonymous method to a local variable with the right type. We rely on the fact that we can convert from an EventHandler<T> to the strongly typed EventHandler delegate. This means that it is also possible to compile code with the wrong event/delegate combinations; but don't worry: the runtime will "inform you" of any conversion failures.

Friday, November 3

I was somewhat surprised to discover that there's no TryParse method for the Enum class in the .NET Framework 2.0. (It's also odd that the docs/compiler keep referring to Enum as a class—and yet the apprpriate where constraint to apply is struct.) So here's a pair of generic methods to support TryParse for Enums: