委托和事件记一笔
每次用到了都忘了,再去查好了。再用又忘了,这里就记一记自己理解的方便自己偶尔看看。
委托,顾名思义,就是可以委托这个东西来调用哪个(与它匹配的)方法。委托是一种类型,用来标识哪些方法可以委托它来调用。
委托是事件的基础。
为什么这么说呢,想想事件是什么,就是在包含它的类(或者其它要触发它的什么东西)里可以直接触发它,然后就不用管触发之后要调用谁了。那么这么一来,你不管要调用谁谁去管调用谁?这里就要用到委托。你委托委托这个东西去调用已经绑定的方法,当然了,这个时候在触发事件的这个类里,你依然不知道你这一触发到底调用了谁的方法。
1 public delegate int CalPlusDelegate(int a, int b);
委托的实例化
我们说委托是一种类型,那么它是怎么实例化的呢?
不难想到,既然是要通过它来调用某个(或某些函数),那么就要通过函数(命名的或者匿名的,或者可以用lambda表达式等,总之就是它要调用的方法块)来实例化它。当然不是所有函数都行,它对实例化的函数还是有要求的:要求签名和委托类相同。委托的签名包括参数类型 和 返回值类型。只要符合上面两个条件,所有函数都可以分配给该委托。
实例化后的委托是一个对象,可以将其赋值给属性,也可以作为参数传递。
1 private PlusTwoInt(int x, int y) 2 { 3 return x + y; 4 } 5 CalPlusDelegate cal1 = PlusTwoInt;
从以上代码的第5行我们可以看出,委托就像C++的函数指针或引用。但委托是类型安全的。
委托的多路广播
我们可以委托一个委托对象来调用多个函数,这时就要用到委托的多路广播 MulticastDelegate,该类的对象通过使用 + 或者 += 来包含多个函数。调用的顺序也和包含的顺序相同,参数的传递也是,如果传递的是指针或者引用类型,在依次调用函数时参数值可能会发生变化。
1 CalPlusDelegate cal1 = new CalPlusDelegate(PlusTwoInt); 2 cal1 += new CalPlusDelegate(PlusTwoDouble); 3 cal1(78, 98);
代码中第三行调用时会先调用 PlusTowInt,然后再调用PlusTwoDouble。
.Net Framework中的事件和委托
.net Framework中的所有事件均是基于EventHandler委托的,该委托有两个参数,一个是触发事件的对象,一个是事件的内容。没有返回值:
public delegate void EventHandler(object sender, EventArgs e);
使用事件和委托
可以自定义一个委托,如果可以的话,尽可能使用.net framework自带的委托,两个参数一个传触发事件的对象,另一个则传事件的内容。
可以自定义事件内容EventArgs类,让它继承自EventArgs,然后添加一些触发事件时要传递的参数。
public class CalPlusEventArgs : EventArgs { private string m_message; public string Message { get{ return this.m_message; } } }
事件的定义和触发
public event CalPlusDelegate CalPlusEvent;
不难看出事件就类似于委托的一个对象,只是前面加了一个event关键字而已。在触发事件的时候,可以这样写,也和委托的调用一样:
if(CalPlusEvent != null) { CalPlusEvent(m, n); }
如果其它地方注册了事件,cal1.CalPlusEvent += new CalPlusDelegate(PlusTwoInt);那么此时CalPlusEvent就不等于null,就会触发事件并依次调用所注册的方法了