delegate本身就是可以串接多个响应函数的。
那么事件发布者把一个delegate公开成一个属性发布出来,观察者去订阅,只要参数列表里面有个object参数,不就完成了event想要做的事情了吗,而且delegate参数列表的内容可以是任意的,不像event那样受限。
那么这么看来,event能做的事情,delegate都能做的很好,
(1) event这个东东是否显得有点冗余呢,
(2) 换句话说,有没有event能方便做到的事情,光用delegate是无法完成的呢?
谢谢!
------解决思路----------------------
event就是Delegate的高级形式,是一种规范语法的语法糖。这就好像你可以自己写套自定义Linq,你也可以用人家标准化接口的Linq,你会说人家的Linq就是多余的吗?
对于一些标准化接口的对象,例如有许多许多控件都有 mouse_moved 事件,它在对象范畴上定义的(而不是在什么方法的参数中定义的),它也不允许在外部被别的程序随便去赋值(也就是说,不能用=操作,只能用+=、-=两个操作)。Delegate能做到这种标准化吗?
event这个关键字的右边就是一个Delegate实例的声明。例如
public static event Action<Membership.BLL.Clean> Alert;这里就是在声明一个Alert委托实例。event用来封装和修饰Delegate,怎么能把它们对立起来呢?
------解决思路----------------------
event作为类的一级成员的各种仁者见仁好处就不讲了。
用event的一个好处是防止对delegate的直接访问。比如:
public class A
{
public EventHandler PropertyChanged;
}
调用者是可以相订阅事件通知一样的订阅:
A a = GetA();
a.PropertyChanged += ...;
但是,调用者也可以y越庖代俎,替A激发‘事件’。
a.PropertyChanged(this, EventArgs.Empty);
而且,调用者还可能覆盖PropertyChanged已经存在的其他订阅(用等于号):
a.PropertyChanged = ...;
------解决思路----------------------
马拉平板车叫做车辆,自行车也叫做车辆,火车也叫做车辆,而奔驰轿车也叫做车辆,你问”有没有奔驰车可以方便做的,而车辆无法做到的?“这类问题,这就是逻辑混淆了。
------解决思路----------------------
你可以说,那么,我的deleage改为私有的,别人就不能随便访问,只能通过公共方法来订阅。不就避免了越庖代俎等问题吗?
这种想法是对的:
public class A
{
private EventHandler PropertyChanged;
public void AddHandler(EventHandler eh)
{
this.PropertyChanged += eh;
}
public void RemoveHandler{EventHandler eh)
{
this.PropertyChanged -= eh;
}
}
其实,event关键词就是帮你做这个的。
public class A
{
public event EventHandler PropertyChanged; // 不是比上述代码简洁吗?
}
------解决思路----------------------
event 本身只是一个用来修饰Delegate语法糖的关键字。而有时候,我们也从语义上,把event看作是一个高级别的Delegate。这两者是不一样的概念,后者是把event跟它所修饰的(右边的)Delegate具体类型声明和变量名称声明混合看成了同一个东西了。
但是如论如何,它跟Delegate都不是对立关系的。而是一般级别和高级的关系。
------解决思路----------------------
世界需要多样性,如果event楼主用不着,别人用得着,呵呵。
我觉得event限制外部调用就很具有规范性,不然事件都被玩坏了啊
------解决思路----------------------
另外,可以额外说明一下关于”用delegate就能实现观察者模式"这个说法的问题。
事件机制在很早就有,而且也已经相当规范,只不过随着不同系统的特点而发展而已。例如在最早最底层的系统中有着大量的中断调用,在汇编语言的大程序中有着大量的查表跳转操作。在visual basic for dos1.0中,就有着完全的事件驱动编程模型,跟今天的事件的定义方式基本上一模一样。定一个事件,不用依赖于监听事件的调用者的类型。
而在很多年以后,GOF(四人帮)不懂事件机制,从而额外多整出了十几个模式(24个中至少有18个是多余的)。所谓观察者模式,在所谓为“被观察者”的对象内部需要依赖于观察者类型定义,需要保存观察者列表。这就产生了令人作呕的复杂的“观察者模式”。
你可以看看事件机制是多么简洁。而观察者模式是多么繁冗,原因就在它将被观察者依赖于观察者。
所以事件机制的初衷不是用来实现什么观察者模式的,而是观察者模式学比它早出现几年出来的标准事件机制的定义学不到家。
------解决思路----------------------
Windows 是消息驱动的系统,本身并无事件的概念
所谓的 event,是 C# 为迎合使用者的喜好而模拟出来的
delegate 说白了就是匿名函数。匿名函数也是函数,只要你知道他的桩,自然就可直接调用。这一点你说的一点都没错
被 event 限定的 delegate 必须只有两个参数,一个用于传递归属者,一个用于传递附加信息
而其他的 delegate 就没有这个限定了。从这点上看,你说的基本上是正确的
event delegate 就是专用的一组函数(方法)
只是 C# 就是用这种方法从消息系统中模拟出事件系统的,所以你也要这么用来定义自己的事件系统
或许哪天 Windows 彻底改写了内核或 C# 找到了更方便的表述方式,你厌恶的冗余就不复存在了