我想将一个事件传递给一个方法。我的代码如下,但我为“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();
}
答案 0 :(得分:5)
你没有 - 事件就像一个属性,它只是一对方法的语法糖(添加/删除而不是属性的get / set)。 F#实际上 将事件公开为头等公民,但C#不会:(
但有几个选择:
传入您要使用要添加的新处理程序调用的“事件订阅者”委托(也可能是事件取消订阅者委托)。像这样:
new Receiver(handler => button.Click += handler, ...)
传入EventInfo
并订阅反映(urgh)
如果我们了解更大的情况,我们可以给出更好的建议 - 关心更多信息?
编辑:好的,所以在这种情况下你需要传递订阅和取消订阅代码:
using (new EventGuard<EventArgs>(h => Proxy.RetrieveCompleted += h,
h => Proxy.RetrieveCompleted -= h,
HandleRetrieveCompleted))
{
...
}
诚然,那是非常令人讨厌的。您可能会发现Reactive Extensions中有更好的东西,但这至少可以起作用......