[C# code]
public delegate void UpdateItem(Object val);
public class MyArrayList : ArrayList {
public void UpdateItems(UpdateItem updater) {
IEnumerator items = this.GetEnumerator();
while (items.MoveNext() == true)
updater(items.Current);
}
}
This certainly compiles. However, because you don't want to create a separate list class for every type
that will be using this delegate, you're also forced to change your
UpdateItem()
delegate's interface,
removing the
Employee
type and replacing it with an
Object
. Still, if this works, what's the big deal?
Well, this change doesn't just impact the new list that was introduced here. It also impacts all of the
methods that implement this
UpdateItem()
delegate. They are all required to convert to
Object
-based
interfaces. And, of course, this means that you're stuck, once again, with a scenario that requires each
delegate implementation to cast its incoming
Object
parameter to the appropriate type.
Now, contrast these negatives of this non-generic approach with the generic version. Because the
MyList
class descended from a generic list type, that list includes a type parameter that allows the
UpdateItems()
method to work with the specific type being managed by the list. No casts are needed
within the implementation of the method, no object data types need to be used in the delegate's inter-
faces, and no casting is required in the methods that implement the delegate. Overall, this represents a
significant improvement.
So, within this one little method call, the major underlying weakness of the non-generic delegates is
exposed. You should also see how, in using these generic delegates in combination with other generic
types, you get a double bonus -- all that simply because you're able to add type parameters to your
delegates.
Event Handling
Event handlers are often forced to take a less than type-safe approach to handling messages. For this
reason and others, they make excellent candidates for applying generic delegates. Imagine situations in
which you have a non-generic event handler that accepts an
Object
type to represent each event sender.
The declaration of that delegate might appear as follows:
[VB code]
Public Delegate Sub EventHandler(ByVal sender As Object, ByVal args As EventArgs)
[C# code]
public delegate void EventHandler(Object sender, EventArgs args);
This usage of an
Object
type as the type for each sender is no longer necessary with a delegate version
of this interface. In fact, with delegates, you can actually create event handling signatures that support
the specific models required by your application. If you need another parameter for the event, you can
just create a new delegate that adds another type parameter. A generic replacement for this example
would be represented as follows:
105
Generic Delegates
09_559885 ch06.qxd 9/8/05 11:02 PM Page 105