繁体   English   中英

如何在.NET中分配事件

[英]How events are assigned in .NET

我刚刚意识到我并不完全理解为什么在.NET中使用+ =符号分配事件。

昨天当我需要删除一个事件而不考虑我正在做的时候,我想出了这个

someobject.onsomeevent += null

以为这会删除我之前分配的事件。

经过一番调查,我发现我必须这样做

someobject.onsomeevent -= someeventmethod;

在搞清楚之后,我意识到我不明白如何在.NET中分配事件方法。

所以我有几个问题:

首先,这是否意味着我能做到

someobject.onsomeevent += someeventmethod;
someobject.onsomeevent += someeventothermethod;

如果是这样,当onsomeevent发生时,它们都会被命中,并按照指定的顺序或同时进行?

此外,如何确定已将哪些事件方法分配给someobject.onsomeevent

第二,有没有办法在某些类中保存事件方法,从someobject.onsomeevent中删除它们,并在通常触发事件的其他一些程序完成之后重新分配它们?

关于您的第一个问题:默认情况下您会获得多播行为。 也就是说,如果你有多个处理程序,那么默认情况下将按顺序调用事件处理程序(除非其中一个抛出异常)。 请注意,您可以更改add+= )和remove-= )以执行与默认行为不同的操作。

Jon Skeet有一个页面解释您可能想要阅读的C#中的委托和事件

第一个问题:是的,只要方法签名与事件的委托类型兼容,就可以这样做。

第二个问题:是的,你也可以这样做。 使用EventTest.GetInvocationList()获取注册到您的事件的方法。 然后使用-=+=分别删除和重新添加委托。 请参阅以下示例:

  public class Test 
  {
        public event EventHandler EventTest = delegate { };
        public void Method()
        {
            //get registered event handlers
            Delegate[] invocationList = EventTest.GetInvocationList();

            //remove them
            foreach (Delegate d in invocationList)
            {
                EventTest -= (EventHandler)d;
            }

            //this method won't trigger anything, because 
            //invocation list is empty
            Method2();

            //re-add event handlers
            foreach (Delegate d in invocationList)
            {
                EventTest += (EventHandler)d;
            }
        }

        public void Method2()
        {
            if(EvenTest != null)
            EventTest(this, EventArgs.Empty);
        } 
   }

我删除了普通的Main()方法,使代码更具可读性。

所以答案是肯定的,是的,并按顺序添加。

事件是MulticastDelegate类的实例。 要找出分配给事件的代理,请在事件上调用GetInvocationList方法。 请参阅http://msdn.microsoft.com/en-us/library/system.multicastdelegate.getinvocationlist%28v=VS.71%29.aspx

这将为您提供一系列代表。 因此,您可以调用GetInvocationList来获取现有的事件处理程序; 然后从事件中清除事件处理程序; 做一些动作; 然后将处理程序重新分配给事件。

代表在.NET中是“多播”,事件是类似属性的包装器。 通过以长格式表示法查看事件,您可以获得更好的效果:

private EventHandler _handler;

public event EventHandler MyEvent
{
  add { _handler = (EventHandler)Delegate.Combine(_handler, value);  }
  remove { _handler = (EventHandler)Delegate.Remove(_handler, value); }
}

您通常会在1行中写下以上所有内容:

public event EventHandler MyEvent;

并且要完成,事件会占用一个Invocationlist,它会在触发时按顺序处理。 订单无法保证。

只是为了掩盖一点,我认为任何人都没有明确地处理过,事件并非全部同时发生 - 它们按顺序发射......

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM