下面是一个示例(摘自《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,你演警察。”;
警察,你就是管抓贼的,你得管偷东西的事儿。
小偷,你去偷东西吧。 // 肯定被警察逮
警察,忙你的专案吧,抓贼的事儿先放一放。
小偷,再去偷东西。 // 这下小偷乐翻了。
}