Java或C#中的事件/代理

Sao*_*obi 6 c# java delegates event-handling

我一直在努力了解事件/代表,但我对两者之间的关系感到困惑.我知道委托允许您调用不同的函数,而无需知道调用的是什么特定函数.(例如:图形函数需要接受要绘制的不同函数的输入).

但我没有看到代表如何在事件中使用.

有人可以构建一个简单的示例(伪代码或C#或Java),说明代理与事件相关的工作方式吗?

谢谢!

Jon*_*eet 8

(这完全来自C#的观点.)

我有一篇关于事件和代表之间差异文章.这更详细地涵盖了下面提到的所有内容.

基本上我喜欢将事件看作是一个属性 - 它是一对方法,就是这样.而不是获取/设置,事件已添加/删除 - 意味着"添加此事件处理程序"和"删除此事件处理程序".总的来说,这就是一个事件.

C#也有类似字段的事件,这是一个快捷方式:

 public event EventHandler Foo;
Run Code Online (Sandbox Code Playgroud)

声明一个字段一个事件,具有几乎无关紧要的添加/删除实现.在课堂内,指的Foo是该领域.课外,指的Foo是事件.

基本思想是,通过传入委托(事件处理程序),事件允许其他代码订阅和取消订阅.通常,通过创建包含先前事件处理程序列表和新事件处理程序列表的新多播委托来实现订阅.因此,如果您将事件处理程序存储在调用的字段中myEventHandlers,则订阅实现可能是:

myEventHandlers += value;
Run Code Online (Sandbox Code Playgroud)

类似地,取消订阅通常涉及在没有指定处理程序的情况下创建新的多播委托:

myEventHandlers -= value;
Run Code Online (Sandbox Code Playgroud)

然后,当您想要引发/触发事件时,您只需调用该多播委托 - 通常使用无效检查,以避免在没有订阅的情况下抛出异常:

EventHandler handler = myEventHandlers;
if (handler != null)
{
    // You could pass in a different "sender" and "args" of course
    handler(this, EventArgs.Empty);
}
Run Code Online (Sandbox Code Playgroud)

使用事件,订阅者彼此不了解,并且不能自己(通常)提出事件.换句话说,它是一种封装模式,已在语言和平台中获得状态.