代码之家  ›  专栏  ›  技术社区  ›  Phillip Ngan

将事件作为参数传递到方法中

  •  4
  • Phillip Ngan  · 技术社区  · 16 年前

    我想将一个事件传递给一个方法。我有下面的代码,但是我要为“xxx”类型输入什么?

    internal class Retriever<TEventArgs> where TEventArgs : EventArgs
    {
        public Retriever( XXX event, EventHandler<TEventArgs> handler )
        {
            _event = event;
            _handler = handler;
    
            _event += handler;
        }
    
        XXX _event;
        EventHandler<TEventArgs> _handler;
    }
    

    编辑 :阐述问题。我正在尝试编写一个通用的事件保护程序,其中事件在事件发生之前订阅,在事件发生之后取消订阅。这个类看起来像:

    internal class EventGuard<TEventArgs> : IDisposable where TEventArgs : EventArgs 
    {
        public Retriever( XXX event, EventHandler<TEventArgs> handler )
        {
            _event = event;
            _handler = handler;
    
            _event += handler;
        }
    
        XXX _event;
        EventHandler<TEventArgs> _handler;
    
        public void Dispose()
        {
            _event -= _handler;
        }
    }
    

    我会用下面的方法。 Proxy.RetrieveAsync 是一个Web方法,完成后将导致 Proxy.RetrieveCompleted 要激发的事件。完成处理程序的主体 HandleRetrieveCompleted 如果没有显示,将在ManualReseteEvent(作为UserState对象传入)上调用set()。

    using ( new EventGuard<EventArgs>( Proxy.RetrieveCompleted, new  EventHandler<EventArgs>( HandleRetrieveCompleted) ) )
    {
        ManualResetEvent resetEvent = new ManualResetEvent();
        Proxy.RetrieveAsync(resetEvent);
        resetEvent.WaitOne();
    
    }
    
    1 回复  |  直到 16 年前
        1
  •  5
  •   Jon Skeet    16 年前

    您不需要-事件就像一个属性,它只是围绕一对方法(为属性添加/删除,而不是获取/设置)的语法糖分。事实上 将事件公开为头等公民,但C不:(

    但有几个选择:

    • 传递一个“事件订阅者”委托,您使用要添加的新处理程序调用该委托(也可能是一个事件取消订阅者委托)。像这样:

      new Receiver(handler => button.Click += handler, ...)
      
    • 传球 EventInfo 订阅反射(urgh)

    • 看看反应式扩展框架,它有各种处理事件的方法(使用反射,但这意味着微软做反射而不是你)。

    如果我们知道更大的情况,我们可以给出更好的建议——愿意多通知我们吗?

    编辑:好的,在这种情况下,您需要同时传递订阅和取消订阅代码:

    using (new EventGuard<EventArgs>(h => Proxy.RetrieveCompleted += h, 
              h => Proxy.RetrieveCompleted -= h,
              HandleRetrieveCompleted))
    {
        ...
    }
    

    诚然,这很讨厌。你可能会发现里面有更好的东西 Reactive Extensions 但那至少会起作用…