事件处理程序订阅混淆

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了事件处理程序订阅混淆相关的知识,希望对你有一定的参考价值。

我很少需要使用事件,不同语法的数量是有效的,当我有时重新访问它时会让人感到困惑。

我想知道这两次调用之间的根本区别是什么?

public class Foo
{
    public event EventHandler<int> OnBar;
}

var foo = new Foo();

EventHandler<TDTO> handler1 = (object obj, int args) => { /*do work*/ }
EventHandler<TDTO> handler2 = (object obj, int args) => { /*do more work*/ }

foo.OnBar += handler1;
foo.OnBar += handler2;

或者像这样调用

var foo = new Foo();

EventHandler<TDTO> handler1 = (object obj, int args) => { /*do work*/ }
handler1 += (object obj, int args) => { /*do more work*/ }

foo.OnBar += handler1;

您是唯一分离参考文献的人,以便您可以单独取消订阅吗?

或者是否有使用一个而不是另一个的附加价值。

答案

这两种订阅方式之间没有实际区别。常规事件(即 - 不提供自定义addremove的事件)只是代表的一个包装,与你的问题中的handler1(例如)相同的代理。所以你要比较一下:

Action @event= null;
Action a = () => Console.WriteLine("A");
Action b = () => Console.WriteLine("B");
@event += a;
@event += b;

有了这个:

Action @event = null;
Action a = () => Console.WriteLine("A");
Action b = () => Console.WriteLine("B");
a += b;
@event += a;
@event();

并没有区别:在两种情况下,委托@event的调用列表包含代表ab。你甚至可以从调用列表中删除b,即使你从未调用过@event += b

也就是说,将具有多个处理程序的委托传递给事件是非常不寻常的。此外,如果事件DOES为addremove提供自定义实现 - 它可能不会期望这样的委托。例如,如果你两次调用foo.OnBar += ... - 将调用自定义add 2次。但是如果你传递已经合并的委托,你只需要调用一次,所以add也会被调用一次。所以我建议不要这样做,并且总是将单个委托传递给事件,而不是预先组合它们。

以上是关于事件处理程序订阅混淆的主要内容,如果未能解决你的问题,请参考以下文章

全局鼠标事件处理程序

append() 在这个代码片段中是如何工作的?与特定变量混淆[重复]

spring#事件发布订阅

UpdatePanel 异步回发后的 Javascript 事件订阅

微信公众平台开发 订阅事件(subscribe)处理

微信公众平台开发 订阅事件(subscribe)处理