15.8 委托中的协变和逆变

前面我们讲过委托对于它能引用的方法有一定的要求,但这个要求具有一定的灵活性,那就是本节要讲的协变和逆变,我们先来看看什么是协变和逆变:

❑协变:委托方法的返回值类型直接或间接地继承自委托签名的返回值类型,称为协变;

❑逆变:委托签名中的参数类型继承自委托方法的参数类型,称为逆变。

注意 协变强调的是返回类型,逆变强调的则是方法参数。

我们还以之前的打印为例,从代码角度理解协变和逆变。

协变代码示例如代码清单15-6所示:

代码清单15-6 协变代码示例


1 namespace ProgrammingCSharp4

2{

3//打印机类

4 public class Printer

5{

6

7}

8

9//激光打印机类

10 public class LaserPrinter:Printer

11{

12

13}

14

15//委托签名返回值为Printer类型

16 public delegate Printer PrintDelegate();

17

18 public class DelegateSample

19{

20//委托方法的返回值类型是Printer类的派生类

21 public static LaserPrinter PrintWithLaser()

22{

23 return new LaserPrinter();

24}

25

26

27 public static void Main()

28{

29//协变

30 PrintDelegate pd=PrintWithLaser;

31 Printer printer=pd();

32}

33}

34

35

36}


图15-7演示了上述代码。

15.8 委托中的协变和逆变 - 图1

图 15-7 协变图示

逆变代码示例如代码清单15-7所示。

代码清单15-7 逆变代码示例


1 namespace ProgrammingCSharp4

2{

3//打印机类

4 public class Printer

5{

6

7}

8

9//激光打印机类

10 public class LaserPrinter:Printer

11{

12

13}

14

15//委托签名的参数类型为Printer类的派生类:LaserPrinter类型

16 public delegate void PrintDelegate(LaserPrinter laserPrinter);

17

18 public class DelegateSample

19{

20//委托方法的参数类型是Printer类

21 public static void Print(Printer printer)

22{

23 return;

24}

25

26 public static void Main()

27{

28 PrintDelegate pd=Print;

29//逆变

30 pd(new LaserPrinter());

31}

32}

33}


图15-8说明了上述代码的含义。

15.8 委托中的协变和逆变 - 图2

图 15-8 逆变图示