Before contravariance became available,
this wasn??™t useful??”there was no benefit to making the informational parameter
derive from EventArgs, and sometimes there wasn??™t much use for the origin of the
event. It was often more sensible just to pass the relevant information directly in the
form of normal parameters, just like any other method. Now, however, you can use a
method with the EventHandler signature as the action for any delegate type that
honors the convention.
Demonstrating covariance of return types is a little harder as relatively few built-in
delegates are declared with a nonvoid return type. There are some available, but it??™s easier
to declare our own delegate type that uses Stream as its return type. For simplicity
we??™ll make it parameterless:2
delegate Stream StreamFactory();
We can now use this with a method that is declared to return a specific type of stream,
as shown in listing 5.3. We declare a method that always returns a MemoryStream with
Listing 5.2 Demonstration of method group conversions and delegate contravariance
2 Return type covariance and parameter type contravariance can be used at the same time, although you??™re
unlikely to come across situations where it would be useful.
B
Handles
all events
Uses method
group conversion
C
Uses conversion
and contravariance D
143 Covariance and contravariance
some random data, and then use that method as the action for a StreamFactory delegate
instance.
Pages:
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295