For instance, you could create a MethodInvoker from a ThreadStart??”but you
couldn??™t do what we??™re doing in the previous code. We??™re using contravariance to create
a new delegate instance from an existing one with a compatible delegate type signature,
where compatibility is defined in a less restrictive manner in C# 2 than in C# 1.
This new flexibility in C# 2 causes one of the very few cases where existing valid
C#1 code may produce different results when compiled under C# 2: if a derived class
overloads a method declared in its base class, a delegate creation expression that previously
only matched the base class method could now match the derived class
method due to covariance or contravariance. In this case the derived class method
will take priority in C# 2. Listing 5.4 gives an example of this.
Listing 5.3 Demonstration of covariance of return types for delegates
Declares delegate type returning Stream B
C
Declares method
returning MemoryStream
Converts method
group with covariance
D
E
Invokes
delegate
144 CHAPTER 5 Fast-tracked delegates
delegate void SampleDelegate(string x);
public void CandidateAction(string x)
{
Console.WriteLine("Snippet.CandidateAction");
}
public class Derived : Snippet
{
public void CandidateAction(object o)
{
Console.WriteLine("Derived.CandidateAction");
}
}
...
Derived x = new Derived();
SampleDelegate factory = new SampleDelegate(x.
Pages:
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297