委托简述:委托简单来说就是一个可以赋值方法的类型(就如int类型可以赋值数字一样)。所有的委托(Delegate)都派生自 System.Delegate 类。委托是一个类型安全的,面向对象的函数指针。
委托定义:例如 delegate void IntMethodInvoker(int x).上述声明了一个可以指向一个带有一个int 类型的形参,返回值为void 的方法。
字段 | 说明 |
---|---|
delegate | 定义委托的关键字 |
IntMethodInvoker | 委托名 |
void | 指向的方法的返回值 |
int | 指向的方法的形参 |
使用委托:先使用定义的委托类型声明一个委托变量,通过new关键字创建委托实例并为委托赋值,接着像使用方法那样使用委托名调用方法。(既可以引用静态方法也可以引用普通的方法)
委托作为形参:可以将委托类型作为方法的形参传递。
系统预定义的委托:
一、Acition委托:基本的Acition委托只能指向没有返回值没有形参的方法。
例如:Acition a=x.ToString();
二、泛型Acition委托:泛型Acition委托能指向有形参而没有返回值的类型。
例如:Acition<int> a;这个委托a能指向形参为一个int类型返回值为void的方法。
(注意!Acition泛型最多只能支持16个参数)
三、Func委托:Func委托是泛型委托,可以引用带有返回值和形参的方法。最多传递16个参数。例如:Func<int> a 。Func委托的最后一个参数是委托的返回值,前面的参数是方法的形参。上述的代表这个委托可以引用一个返回值为int无参数的方法。
多播委托:(一个委托指向多个方法,一般多播委托的返回值为空)
一、添加方法语法:在一个委托变量已经指向一个方法时,如:Acition a=Text1;
此时在使用+=在这个委托的后面添加一个方法,如:a+=Text2;
这样就会根据指向的顺序执行方法,上述先执行Text1在执行Text2。
二、删除方法语法:一个已经指向两个或以上的委托变量删除一个方法使用 -=, 如上述委托a: a-=Text2。这样在调用a时就不会执行方法Text2了。
三、获取多播委托的所有方法:使用多播委托的GetInvocationList()方法可以获取多播委托的所有方法。GetInvocationList()方法返回一个Delegate的数组。获取出来的数组元素可以调用DynamiCINvokee()方法单独执行。
注意!!!调用一个空的委托会出现空指针异常,解决方法:在调用委托时判断委托是不是空委托如:if(a!=null)。
多播委托的一个方法出现异常时,在这个方法后面的方法都不会执行。
四、匿名方法:
定义:将方法的方法名用delegate关键字来代替,不用声明返回值类型,直接写return。
使用:匿名方法因为没有方法名所以不能直接调用只能赋值给委托来使用。如:
Func<int, int, int> plus1 = delegate (int arg1, int arg2)
{
return arg1 + arg2;
};
五、Lambda表达式
简述:Lambda表达式是匿名表达式的简写。用来替代匿名方法,Lambda表达式也只能赋值给委托来使用。Lambda表达式的参数不需要声明类型,如:
Func<int, int, int> plus = (arg1, arg2) =>
{
return arg1 + arg2;
};
Lambda运算符 “=>“的左边列出了需要的参数,如果只有一个参数就不用括号包含,同样如果方法提只有一条语句也不用花括号和return。
六、事件(事件是受限制的委托,委托的特殊使用)
声明事件:在定义了委托类型后,在声明委托时加入event关键字就可以声明事件(编译成创建一个私有委托的实例,它只能通过+=,-=来操作)。事件的使用方法与委托一样。
事件与委托的区别:
区别一(最大区别) | 委托能通过对象进行调用,和注册。事件能通过对象进行注册但不能通过对象进行触发,它只能在类里面进行触发。事件比委托更加安全(最好不要在类的外部触发委托) |
区别二 | 事件只能作为类的成员不能作为局部变量,委托变量则既可以作为类的成员还可以作为局部变量。 |
区别三 | 委托常用来表示回调,事件常用来表达外发的接口。 |
事件的意义:事件基于委托,为委托提供了发布/订阅机制。是类或对象向其他类或对象通知发生的事情的一种特殊签名的委托。
事件命名:名字的尾部加上Event。
七、事件的应用:观察者设计模式
简述:在这个设计模式中有一个被观察者和多个观察者,观察者根据被观察者的状态做出不同反应。
具体实现:被观察者中提供一个事件,观察者将反应的方法注(+=)册进这个委托中,当被观察者状态改变时就调用这个委托,执行所有注册过的观察者的反应方法。