C#委托和事件的使用示例
一、委托
书本上的bai委托只是对委托的定义与具体怎样调用问题,没有涉及到委托的真正实用的地方。其实委托是与事件和回调
一起来使用的,你可以看一下C#异步调用,与多线程处理里等就可以看到委托的作用了。
使用委托时要先实例化,和类一样,使用new关键字产生委托的新实例,然后将一个或者多个与委托签名匹配的方法与委托实例关联。随后调用委托时,就会调用所有与委托实例关联的方法。
与委托关联可以是任何类或者结构中的方法,可以是静态方法,只要是可以访问的方法都可以。
1.创建一个委托类型使用关键字delegate(委托)
输出如下:
2.一个委托实例,可关联多个方法:
其中D4 = TestMethod1;用“=”而不能“+=”,是因为之前D4未实例化,可以使用下面的代码:
MyDelegate D4 = new MyDelegate(TestMethod1); D4 += TestMethod2; D4 += TestMethod3;
但是如果使用以下方式,会出现编译错误: “MyDelegate”方法没有采用“0”个参数的重载:
MyDelegate D4 = new MyDelegate(); D4 += TestMethod1;
详情见:http://www.tracefact.net/tech/009.html
3.移除一个委托实例中的方法 使用“-=”:
委托的理解:
1)有了委托你就可以把方法看作像常数一样,而委托就是该常数类型的变量.
从这个角度看来用于声明事件的委托就是声明这个事件触发以后所调用的方法的标签或者特征.只有符合该标签(参数个数和参数类型)的方法才可以做为该用于该事件的回调.
一个事件触发了,你可能需要用多个方法处理该事件或者说该事件调用了多个方法(每个事件的实例都有一个需要调用的方法列表,当事件触发它会逐个调用列表中的每个方法)
2)通过使用委托你可以实现对方法变化的封装.
打个比方:如果你骑自行车,你需要有骑自行车的方法DriveBike().如果你骑摩托车你需要有骑摩托车的方法.现在你有一个方法DriveMoto.现在你需要定义一个方法,实现你骑(自行车或者摩托车)到某地DriveTo(地点,骑的方式)
骑的方式这里其实就是委托.在使用的时候,如果你是骑自行车你就用DriveBike实例化委托的实例带入DriveTo方法,如果你骑摩托车你就用DriveMoto实例化"骑的方式"这个委托带入DriveTo方法.
以通俗的理解为将一个方法作为参数传递给另一个方法!也可以理解为:现有N个参数和返回值都相同的方法,在使用的时候根据需要一个个调用太繁琐,干脆把这些方法的规律(方法参数和返回值)总结出来,定义成一个委托!然后把要执行的方法交给委托去执行!+=操作实际上就是委托链,委托一次代理了若干个方法,以后执行时,我们调用委托来执行,委托会把所代理的方法一个个再执行!
委托在.net1.0就有,到了2.0时出现了匿名方法,也就是说委托要执行某一个方法,而这个方法并没有事先定义,随用随定义,连名字都没取,所以叫匿名方法。例:委托实例=delegate(int x,int y){return x+y;}实际就指向一个未取名的方法,而这个方法接收两个int参数,返回和。
到了.net3以后又更进一步,匿名方法还可以简写成:委托实例=(x,y)=>x+y; 这就是传说中的Lambda表达式,其本质是匿名方法,匿名方法本质是委托!
先通俗理解后,再看文档,你会恍然大悟!委托、匿名方法、Lambda表达式的概念其实很重要,如果你不理解的话是没办法学习好LinQ的。
事件由委托来实现的
1 public delegate void EventHandle(object sender,eventArgs e);//定义委托
2 public event EventHandle MyDIYEvent;//定义事件
委托还有一个用法是异步
二、事件
事件自身就是委托类型,由于委托可以绑定和调用多个方法,所以会为事件的处理带来方便。类型只需要对外公开事件,就可以与外部的其它地方关联,从而实现事件订阅
要在类中声明事件(只不过不管是不是声明为public,它总是被声明为private。另外,它还有两个方法,分别是add_MakeGreet和remove_MakeGreet,这两个方法分
别用于注册委托类型的方法和取消注册。实际上也就是: “+= ”对应 add_MakeGreet,“-=”对应remove_MakeGreet。而这两个方法的访问限制取决于声明事件时的访问限制符。)
1.首先要定义用来作为事件封装类型的委托,用event关键字来声明事件。
2.为了允许派生类重写引发事件的代码,通常会在类中声明一个受保护的方法,习惯上命名On<事件名>
3.EventArgs类参数
由于不同的事件要传递的参数不同,更多时候是从EventArgs类派生的子类的实例,显然EventHandler委托时不能满足各种情况的。
如果针对不同的事件也定义一个对应的委托,数量一旦多起来,不好管理,为了解决这个问题,.NET类库提供了一个带有泛型参数的事件
处理委托:
public delegate void EventHandler<TEventArgs>(object sender,TEventArgs e); TEventArgs 是一个泛型参数