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

关于 C# 委托、事件

2008-04-12 14:37 281 查看
2006-09-25 17:47:21 dd()
谁对C#中 委托 了解比较多的?

2006-09-25 17:49:41 dd()
[?]

2006-09-25 17:52:20 AfritXia()
怎么?

2006-09-25 17:54:24 dd()
我感觉委托和 直接的函数调用很相似

2006-09-25 17:54:45 dd()
那委托在什么地方 强过 函数调用呢?

2006-09-25 17:57:24 AfritXia()


2006-09-25 17:57:43 AfritXia()
这个就是婉转的表达了

2006-09-25 17:58:40 AfritXia()
当你要调用的函数,还不能确定函数的执行体时,这时委托就隆重登场

2006-09-25 17:58:57 dd()
实现调用的多态?

2006-09-25 17:59:05 AfritXia()


2006-09-25 17:59:20 dd()
恩,有点道理

2006-09-25 18:00:19 AfritXia()
例如点击按钮后,将文本写入到磁盘

2006-09-25 18:01:06 AfritXia()
但是对于按钮这个控件的开发者来说,他不能确定这个控件在按下后,会发生什么事情

2006-09-25 18:01:29 AfritXia()
所以,他只好留个活口

2006-09-25 18:02:29 dd()
了解

2006-09-25 18:02:56 AfritXia()
恩恩

2006-09-25 18:03:20 AfritXia()
其实在 C 语言上,就是指针函数

2006-09-25 18:05:27 dd()


2006-09-25 18:06:23 dd()
感觉其实用处也不是特别大

2006-09-25 18:09:29 AfritXia()
委托?

2006-09-25 18:09:50 dd()
是啊

2006-09-25 18:10:22 AfritXia()
很大的,事件就是委托

2006-09-25 18:13:11 dd()
.NET系统是利用委托作了很多事

2006-09-25 18:13:34 dd()
但是,对于开发者来讲,委托的用处我觉得不是特别大啊

2006-09-25 18:14:35 AfritXia()


2006-09-25 18:14:56 dd()
sigh

2006-09-25 18:15:16 AfritXia()
如果你开发的是一个事件驱动的系统,应该会用到很多

2006-09-25 18:15:28 dd()
en

2006-09-25 18:15:48 dd()
也就是写WIN FORM应用的时候,应该有比较大的用处

2006-09-25 18:16:30 AfritXia()
不完全是噢

2006-09-25 18:16:42 dd()
恩?

2006-09-25 18:16:48 dd()
还在哪里有用?

2006-09-25 18:17:02 AfritXia()
你知道设计模式吗?

2006-09-25 18:17:32 dd()
恩?

2006-09-25 18:17:37 dd()
知道一点

2006-09-25 18:18:21 AfritXia()
设计模式中,一个原则,蒂米特法则

2006-09-25 18:18:50 dd()


2006-09-25 18:19:05 AfritXia()
其大意是指:类应该尽量的无知

2006-09-25 18:19:45 AfritXia()
这样,在修改一个类的时候,才不会引起连锁反应

2006-09-25 18:19:59 AfritXia()
我举个例子

2006-09-25 18:21:12 dd()


2006-09-25 18:21:19 AfritXia()
一个类 A,在调用了成员函数 MethodA 后,需要 调用 B 类的成员方法 MethodB

2006-09-25 18:21:55 dd()


2006-09-25 18:22:00 AfritXia()
class A
{
public void MethodA()
{
(new B()).MethodB();
}
}

2006-09-25 18:22:22 AfritXia()
class B
{
public void MethodB() { ... }
}

2006-09-25 18:22:40 AfritXia()
这里的 A 设计的是不好的

2006-09-25 18:22:55 AfritXia()
因为,A 知道了 B

2006-09-25 18:23:41 AfritXia()
假设,B 的 MethodB 换名了,改成了 Method__B

2006-09-25 18:23:53 AfritXia()
那么就会影响到类 A

2006-09-25 18:24:17 dd()
的确

2006-09-25 18:24:27 AfritXia()
根据刚才的原则,我们可以把 B 从 A 中清除出去

2006-09-25 18:24:55 AfritXia()
这样,这两个类,就都干净了

2006-09-25 18:25:09 dd()
用一个共同的基类?

2006-09-25 18:25:27 AfritXia()
但是我又必须达到 A 的调用结束后,必须调用 B

2006-09-25 18:25:38 AfritXia()
那么这里就可以使用事件

2006-09-25 18:26:04 dd()
继续

2006-09-25 18:26:23 AfritXia()
事件机制,很好的将两个关联的类分开

2006-09-25 18:28:16 dd()


2006-09-25 18:29:53 AfritXia()
class A
{
public delegate Call();

private event Call m_onCall;

public void MethodA()
{
if (this.OnCall != null)
this.OnCall();
}

public event Call OnCall
{
add
{
this.m_onCall += value;
}

remove
{
this.m_onCall -= value;
}
}
}

2006-09-25 18:30:14 AfritXia()
这样你看不见 A 中有 B

2006-09-25 18:31:33 AfritXia()
在主程序中:

A a = new A();

a.OnCall = new A.Call(A_OnCall);

public void A_OnCall()
{
(new B()).MethodB();
}

2006-09-25 18:32:21 AfritXia()
假如,我现在有了个类 C,在 A 调用过 MethodA 后还要调用 C 类的 MethodC

2006-09-25 18:33:00 AfritXia()
原来的程序:

class A

{

public void MethodA()

{

(new B()).MethodB();
(new C()).MethodC();

}

}

2006-09-25 18:33:17 dd()
它的限制是 在类B中的函数的参数和返回值必须和类C中的一致

2006-09-25 18:33:52 AfritXia()
你看看,仅仅是加了个新“功能”,还得修改原来的代码……

2006-09-25 18:34:27 AfritXia()
可是,用事件,就不用了,至少我们保证了 A 的纯洁

2006-09-25 18:35:17 dd()
了解了

2006-09-25 18:35:20 AfritXia()
A a = new A();

a.OnCall = new A.Call(A_OnCall);

public void A_OnCall()

{

(new B()).MethodB();
(new C()).MethodC();

}

2006-09-25 18:35:34 dd()
的确是很好
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: