什么是委托
委托类型和委托实例
委托类型
委托类型定义了委托实例可以调用的那类方法,具体来说,委托类型定义了方法的返回类型和参数
delegate int Transformer(int x); //定义委托为int类型,参数为int类型的
static int Square(int x){return x*x;}
//委托就可以调用这个方法,它俩的返回类型和形参是一致的
上面的方法也可以写成static int Square(int x) => x*x;的形式
委托实例
把方法赋值给委托变量的时候就创建了委托实例
Transformer t = Square;
//完整写法:
Transformer t = new Transformer(Square);
调用:
int answer = t(3);
// answer is 9
完整写法: t.Invoke(3)
委托的实例其实就是调用者的委托:调用者先调用委托,然后委托调用目标方法。
间接的把调用者和目标方法解耦合了。
完整例子:
编写插件式的方法
委托可以编写插件式方法
因为 方法是在运行时,才赋值给委托变量的
多播委托
所有的委托实例都具有多播的能力。一个委托实例可以引用一组目标方法。
怎么实现委托一组方法呢:
- +和+=操作符可以合并委托实例
SomeDelegate d = SomeMethod1;
d += SomeMethod2; //(d = d + SomeMethod2)
- +和+=操作符可以合并委托实例
调用d就会调用SomeMethod1和SomeMethod2
- 委托的调用顺序与它们的定义顺序一致
- 委托可以合并,当然可以移除:
- -和-=会把右边的委托从左边的委托里移除
d -= SomeMethod1
委托变量使用+或+=操作符时,其操作数可以是null。就相当于把一个新的值赋给了委托变量。
SomeDelegate d = null;
d += SomeMethod1;
//相当于
d = SomeMethod1;
对单个目标方法的委托变量使用-=操作符时,就相当于把null值赋给了委托变量。
SomeDelegate d = SomeMethod1;
d -= SomeMthod1
//相当于
d = null;
原理:
委托是不可变的
使用+=或-=操作符的,实际上是创建了新的委托实例,并把它赋给当前的委托变量
如果多播委托的返回类型不是void,那么调用者从最后一个被调用的方法来接受返回值。前面的方法仍然会被调用,但是其返回值就被弃用了。
所有的委托类型都派生于System.MulticastDelegate,而它又派生于System.Delegate
C#会把作用于委托的+,-,+=,-=操作编译成使用System.Delegate的Combine和Remove两个静态方法。
例子