您的位置:首页 > 编程语言 > C#

大马哈鱼的C#学习笔记(2):delegate和event

2011-04-14 14:47 344 查看
1.声明delegate

public delegate int myDelegate(string str);

以上语句声明了一个委托,它可以代表返回值为int,参数为string的任何方法(static或者实例方法均可)。

实际上以上语句会被展开为形如:

sealed class myDelegate:
System.MulticastDelegate

{

//blabla,到底怎么实现咱们不用管,反正会从MulticastDelegate继承,MulticastDelegate

//继承自Delegate类

//大致上,有Invoke/BeginInvoke/EndInvoke/DynmaicInvoke等几个方法,都是托管代码,

//用户控制不了

}

另外,WP7中,System名字空间下,已经声明了一个名叫Action的delegate,代表了无返回无参数的方法签名,我们可以直接拿来用。

namespace System

{

public delegate void Action();

}

2.使用Delegate实例

假设有以下的两个方法,它们的返回值和参数类型正好跟myDelegate的吻合,于是它们就可以被myDelegate代表了。

public int func1(string str) {}

public int func2(string str) {}

//实例化一个委托,注意到实例化的时候一定要传入一个方法名而不能为空,因为一个委托至少要代表一个方法吧

myDelegate d1 = new myDelegate(func1);

//当然,我们可以使用 -= 操作符将func1从d1的InvocationList中移除:

//d1 -= func1;

//不过,这样在运行时会抛异常,因为InvocationList为空

//往d1中继续追加func2

d1 += func2;

我们可以随时手动调用d1所关联的方法:

int aa = d1(“abc”);

以上会导致func1和func2依次被调用,虽然它们实际上什么都没做。

//在工作线程中异步调用:

Dispatcher.BeginInvoke(d1, “hello”);

3.通过Delegate.CreateDelegate方法实例化一个Delegate,而不是通过delegate关键字来声明固定特征的委托(当然,一般情况下可能用得很少)

http://msdn.microsoft.com/zh-cn/library/53cz7sc6(v=vs.80).aspx

4.事件(event

event是特殊的委托,比如:

public event EventHandler ClickEvent;

声明了一个名叫ClientEvent的事件。再看EventHandler是什么东东:

namespace System

{

public delegate void EventHandler(object sender, EventArgs e);

}

它位于System名字空间下,其实就是一个规定了特定参数列表的委托。

很显然,我们完全可以这样用:

public EventHandler ClickEvent;

即不加event关键字,这样完全可以跟加上event关键字后一样工作,但是加上event后有一个附加功能:防止在本类外面被直接调用。也就是说,不加event时,外界可以通过xxx.ClickEvent(yy,zz);来进行触发,而这往往不是我们想要的。所以加上event关键字,来防止外界仿冒事件的生成。

xxx. ClickEvent += new EventHandler(click); //或者直接简写为xxx.ClickEvent +=
click;

void click (object sender, EventArgs e)

{

//do something

}

自定义事件

既然事件本质上是委托,那自定义事件就比较好理解了。

public class XXXX

{

public delegate int MyDelegate(int abc);

public event MyDelegate MyEvent;

private int OnMyEvent(int abc)

{

return
abc + 1;

}

public static Main()

{

MyEvent
+= OnMyEvent;

//测试,抛出事件

MyEvent(1); // OnMyEvent将会得到调用

}

以上是个很简单的例子,当然,以上代码没有任何意义,通常情况下,是由另一个类的实例yyyy来调用xxxx.MyEvent += yyyy.SomeFunc;

然后xxxx 在某个特定条件下调用MyEvent(1);(或者Invoke/BeginInvoke) 来抛出事件,使得yyyy的SomeFunc得到调用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: