|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Must event delegates follow the "conventional" form?delegates in the .NET Framework have two parameters: The source that raised the event, and the data for the event [which is an instance of the EventArgs class, or of a class that's derived from EventArgs]." It seems that this convention results in twice as much work whenever we have custom arguments for an event handler. Specifically, we must define: 1. A custom data class, which is derived from EventArgs; and 2. (for maximum type safety) A custom event delegate, which takes an instance of the aforementioned data class as its second argument. On the other hand, if we DON'T follow the convention, then we can simply define: 1. A custom event delegate whose arguments are simply the custom data values, listed directly. Does anyone know: Is there any TECHNICAL reason that we should follow the convention? In other words, is there any aspect of the .NET framework that DEPENDS upon the convention being followed? Thanks, Jeff Brown > Does anyone know: Is there any TECHNICAL reason that we should follow the No, there is nothing that forces it.> convention? In other words, is there any aspect of the .NET framework that > DEPENDS upon the convention being followed? The benefit comes in that adding new parameters does not require changing the signature of every subscriber. Hi,
> Does anyone know: Is there any TECHNICAL reason that we should follow If I remember well, events complying with that convention benefit from > the convention? In other words, is there any aspect of the .NET > framework that DEPENDS upon the convention being followed? some optimizations from the framework and / or from the compiler. Also, there *are* good technical reasons for following this convention. Quoting Shawn Burke from MS: " The .NET architecture certainly allows you to define your delegate signatures any way you like. When you write your software, you're certainly entitled to do so. When we went about the business of writing a collection of objects as large as the .NET Framwork, we knew from the beginning that consistancy was important. As a developer, it really bothers me when pieces of the same product look and act completely differently. So we sat down and crafted a set of what design guidelines or "design patterns" that our classes should conform to. The idea is that a user should be able to move among the different areas of the .NET Framework as easily as possible. One way to do that is to have common naming, eventing, and signature types across the framework. The decisions we made usually had solid technical reasons behind them, but that doesn't mean there are other vialble options or better solutions for specific problems. In the case of event handlers, we established the pattern you see for a couple of reasons: 1) Ease of calling and defining (simplicity). The more parameters we had, the more a user has to type to create a handler for them. Think about when you need to override a function with a whole bunch of arguments. It's kind of a pain to type out all those paramaters when you may not be interested in handling them 2) Reusability. By keeping the signatures consistant, we increased the likelyhood that we wouldn't need yet another class of handlers for a given type of event -- reuse is good since it keeps namespaces smaller, has need for less documentatoin, etc. 3) Modifyable values. Many of our *EventArg classes have data in them that can be specified or modified by the event handlers. For example. the KeyEventArgs class has a read/write Handled property that can be set to "true" by handler function if the key should not be passed to the default handler and processing stopped. You can't do this with normal params (unless they're passed byref which just adds a little more complexity. 4) Extensibility. Having a base class allows us to add functionality (we don't have plans for this, but if push came to shove it's an option) without breaking people. Hypothetically, say users were screaming for the new size in the Resize event, which is currently just a plain EventHandler. Well, we could derive a ResizeEventArgs from EventArgs and pass that into the existing handler without breaking anybody's code. Folks that cared about it could check the type, do a cast, and get the extended info. " |
|||||||||||||||||||||||