将事件作为参数传递给方法

时间:2010-02-11 17:54:13

标签: c# events

我想将一个事件传递给一个方法。我的代码如下,但我为“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的主体(未显示)将调用ManualResetEvent上的Set()(作为UserState对象传入)。

using ( new EventGuard<EventArgs>( Proxy.RetrieveCompleted, new  EventHandler<EventArgs>( HandleRetrieveCompleted) ) )
{
    ManualResetEvent resetEvent = new ManualResetEvent();
    Proxy.RetrieveAsync(resetEvent);
    resetEvent.WaitOne();

}

1 个答案:

答案 0 :(得分:5)

你没有 - 事件就像一个属性,它只是一对方法的语法糖(添加/删除而不是属性的get / set)。 F#实际上 将事件公开为头等公民,但C#不会:(

但有几个选择:

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

    new Receiver(handler => button.Click += handler, ...)
    
  • 传入EventInfo并订阅反映(urgh)

  • 查看Reactive Extensions框架,它有各种处理事件的方法(使用反射,但这意味着Microsoft会进行反射工作而不是您:)

如果我们了解更大的情况,我们可以给出更好的建议 - 关心更多信息?

编辑:好的,所以在这种情况下你需要传递订阅和取消订阅代码:

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

诚然,那是非常令人讨厌的。您可能会发现Reactive Extensions中有更好的东西,但这至少可以起作用......