C# · 12月 20, 2021

[读书笔记]C#学习笔记二: 委托和事件的用法及不同.

前言: 

                                                                                                                                                                                         

c#中的委托可以理解为函数的一个包装,它使得C#中的函数可以作为参数来被传递,这在作用上相当于C++中的函数指针. C++用函数指针获取函数的入口地址,然后通过这个指针来实现对函数的操作.

委托的定义和方法的定义类似,只是在定义的前面多了一个delegate关键字.

委托可以被视为一个更高级的指针,它不仅仅能把地址传指向另一个函数,而且还能传递参数,返回值等多个信息。 系统还为委托对象自动生成了同步,异步的调用方式,开发人员使用BeginInvoke,EndInvoke方法就可以抛开Thread而直接使用多线程调用。

用IL 分析可看出Delegate继承自System.MulticastDelegate类,并自动生成BeginInvoke,EndInvoke,Invoke三种常见的方法。

Invoke方法是用于同步调用委托对象的对应方法,而BeginInvoke,EndInvoke是用于以异步方式调用对应方法的。

1.1 简单的委托当建立委托对象时,委托的参数类型必须与委托方法相对应。只要向建立委托对象的构造函数中输入方法名称example.Method,委托就会直

接绑定此方法。使用myDelegate.Invoke(string message),就能显式调用委托方法。但在实际的操作中,我们无须用到 Invoke 方法,而只要直接使用myDelegate(string message),就能调用委托方法。

MyDelegate( Method( Main( Example example= MyDelegate myDelegate= myDelegate( }

1.2 带返回值的委托

当建立委托对象时,委托的返回值必须与委托方法相对应。使用下面的例子,方法将返回 “Hello Leslie” 。

MyDelegate( Method( + Main( Example example= MyDelegate myDelegate= message = myDelegate( }

1.3 多路广播委托在上面提过,委托类继承于MulticastDelegate,这使委托对象支持多路广播,即委托对象可以绑定多个方法。当输入参数后,每个方法会按顺序进行迭代处理,并返回最后一个方法的计算结果。下面的例子中,Price 类中有两个计算方法,Ordinary 按普通的9.5折计算,Favourable 按优惠价 8.5 折计算。委托同时绑定了这两个方法,在输入参数100以后,Ordinary、Favourable这两个方法将按顺序迭代执行下去,最后返回 Favourable 方法的

计算结果 85。

MyDelegate( Ordinary( price1 = * Console.WriteLine(+ Favourable( price1 = * Console.WriteLine( + Main( Price price = MyDelegate myDelegate = myDelegate += Console.WriteLine( + myDelegate( }

1.4 Observer模式中的事件与委托 

Main( ConcreteSubject subject = subject.Attach( ConcreteObserver(subject, subject.Attach( ConcreteObserver(subject, subject.Attach( ConcreteObserver(subject, subject.SubjectState = observerDelegate += observerDelegate -= (observerDelegate != SubjectState { ; ConcreteObserver(ConcreteSubject subject, .subject = .name = observerState = Console.WriteLine( }

二,事件 event

(1) 事件时委托的封装,可以理解为一种特殊的委托。(2) 事件里面其实就两个方法(即add_event() 和 remove_event())和一个私有的委托变量,这两个方法里面分别是对这个私有的委托变量进

行的合并和移除,当调用事件的+=时其实是调用的事件里的add_event()方法,同样-=调用的是remove_event()方法(3) 事件只能够从对象外部增加新的响应方法和删除已知的响应方法,而不能主动去触发事件和获取其他注册的响应方法等信息。如果使用

公有的delegate则不能做这些限制,也就是说事件对委托做了限制,使委托使用起来更加方便。也有人说事件是对委托的阉割,大概也是这个意思。

这里事件没有做过多的阐述,看到一个关于事件讲解的比较不错的博文,推荐大家看下吧: http://www.cnblogs.com/landeanfen/p/4721525.html