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

理解C#中的事件与委托

2008-10-29 17:48 477 查看
下面是一个示例(摘自《C#面向对象编程》 周长发编著
电子工业出版社出版 348-349页)。如果你不喜欢直接看代码,可以先看后面的分析,等有点眉目的时候再看代码。

示例代码:

// Event.cs

// 事件示例

Using System;

// 1. 发布事件的类:事件触发者

Public class TestEventSource

{

//
ƒ 定义事件参数类

Public
class TestEventArgs : EventArgs

{

Public readonly char KeyToRaiseEvent;

Public TestEventArgs(char
keyToRaiseEvent)

{

KeyToRaiseEvent =
keyToRaiseEvent;

}

}

// ‚ 定义委托

Public delegate
void TestEventHandler(object sender, TestEventArgs e);

//  用Event关键字声明事件对象

Public event
TestEventHandler TestEvent;

// 4 事件触发方法

Procted virtual
void OnTestEvent(TestEventArgs e)

{

if(TestEvent != null)

{

TestEvent(this, e);

}

}

// 5 引发事件

public void
RaiseEvent(char keyToRaiseEvent)

{

TestEventArgs e = new
TestEventArgs(keyToRasiseEvent);

OnTestEvent(e);

}

}

// 2. 侦听事件的类:事件侦听者

public class TestEventListener

{

//
1 定义处理事件的方法,它与声明事件的delegate具有相同的参数和返回值类型

public void
KeyPressed(object sender, TestEventSource.TestEventArgs e)

{

Console.WriteLine(“发送者为:{0},所按的键为:{1}”,sender,e.KeyToRaiseEvent);

}

// ‚ 订阅事件

public void
Subscribe(TestEventSource eventSource)

{

eventSource.TestEvent += new
TestEventSource.TestEventHandler(KeyPressed);

}

// ƒ 取消订阅事件

public void
UnSubscribe(TestEventSource enentSource)

{

eventSource.TestSource.TestEvent -=

new TestEventSource.TestEventHandler(KeyPressed);

}

}

// 3. 测试类:导演

public class Test

{

pubic static
void Main()

{

//  创建事件源对象:触发者

TestEventHandler es = new TestEventSource();

// ‚ 创建事件侦听对象

TestEventListener el = new TestEventListener();

// ƒ 订阅事件

Console.WriteLine("订阅事件/n");

el.Subscribe(es);

// 4 引发事件

Console.WriteLine("请输入一个字符,再按Enter键:");

string s = Console.ReadLine();

es.RaiseEvent(s.ToCharArray()[0]);

// 5 取消事件订阅

Console.WriteLine("取消事件事件订阅/n");

el.UnSubscribe(es);

// 6 引发事件

Console.WriteLine("请输入一个字符,再按Enter键:");

string s = Console.ReadLine();

es.RaiseEvent(s.ToCharArray()[0]);

}

}

分析:

1. 事件触发者:

① 我能做一件事:我做完这件的事件的时候会告诉别人,好让他接着做下面的事儿,但是那个人继续操作的时候必要符合下面‚的要求。

② 我做这件事要有两个参与对象,除了我以外还要有个操作对象,不能我一个人玩空的。

③ 这就是我完成这件事要操作的对象,具体是啥那就要看情况了。

④ 我能做这件事,并且做完了我会告诉别人继续做下面的工作。如果下面没有后续工作了,你得支一声,别耍我。要是我找不到人,那我可就啥也不管了。

⑤ 你给我发这个命令的时候,我就做这件事了。

2. 事件侦听者

① 我有个预案,当有人告诉我说某事发生的时候,我就要按这个预案来行动了。

② 你得告诉谁干了什么事儿的时候,我要按上面的预案行动。也就是说,你要告诉我我该管谁的啥闲事儿。

③ 你要不想让我管了,你也支一声,我就不搭理他,让他随便折腾去。

3. 导演

① 那个演员A,知道你是干嘛的不?你呀,你就是去那找事的。

② 那个演员B,知道你是干嘛的不?你呀,你是那管闲事的。

③ 我说演员B,你放心,只要演员A去做了事件1,你肯定能得着信儿,我找人通知你。

④ 那个演员A,你就别闲着了,你去做事件1去吧。

⑤ 演员B呀,你先歇会儿,A要是再去做事件1,你就别搭理他了。

⑥ A,再跑一趟,再去做一次事件1。

编剧本:

public class 贼

{

public class 一件东西:操作对象

{}

public delegate void 偷东西事件的处理预案(贼,脏物);

public event 偷东西事件的处理预案 偷东西;

(这个事件要由符合“偷东西事件的处理预案”的解决方案来处理。)

protected virtual void 偷了东西要在这报告(脏物)

{

如果有警察抓

那他就给我来个人脏俱获;

}

public void 偷东西(脏物)

{

我瞄上一件东西

……(此处省略偷窥过程)

报告:我得手了。

}

}

public class 警察

{

public void 有贼偷东西的解决预案(贼,脏物)

{

把贼抓住,把脏物还给失主;

}

public void 得管窃案(贼)

{

// 好警察

监视贼的一举一动;

}

public void 不管窃案(贼)

{

// 可能是什么大案子的专案组的,忙,没空儿

不管小贼;

}

}

public class 导演

{

“演员A,你演小偷。”;

“演员B,你演警察。”;

警察,你就是管抓贼的,你得管偷东西的事儿。

小偷,你去偷东西吧。 // 肯定被警察逮

警察,忙你的专案吧,抓贼的事儿先放一放。

小偷,再去偷东西。 // 这下小偷乐翻了。

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: