This is a
bit of a pain, but you can still be slightly briefer than in C# 1 by making the conversion
explicit. For example:
Delegate invalid = SomeMethod;
Delegate valid = (ThreadStart)SomeMethod;
As with generics, the precise rules of conversion are slightly complicated, and the ???just
try it??? rule works very well: if the compiler complains that it doesn??™t have enough
information, just tell it what conversion to use and all should be well. If it doesn??™t complain,
you should be fine. For the exact details, consult the language specification.
Speaking of possible conversions, there may be more than you expect, as we??™ll see in
our next section.
5.3 Covariance and contravariance
We??™ve already talked quite a lot about the concepts of covariance and contravariance
in different contexts, usually bemoaning their absence, but delegate construction
is the one area in which they are actually available in C#. If you want to refresh
yourself about the meaning of the terms at a relatively detailed level, refer back to
section 2.3.2??”but the gist of the topic with respect to delegates is that if it would be
valid (in a static typing sense) to call a method and use its return value everywhere
that you could invoke an instance of a particular delegate type and use its return
value, then that method can be used to create an instance of that delegate type.
Pages:
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292