tags:

views:

72

answers:

1

I want to pass an event into a method. The code I have is as follows, but what do I put for the type "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;
}

Edit: Elaboration of the question. I'm trying to write a generic event guard, where the event is subscribed to prior to an event occurring, and unsubscribed after the event has occurred. This class would look like:

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;
    }
}

and I would use it the following way. Proxy.RetrieveAsync is a web method, which upon completion would cause the Proxy.RetrieveCompleted event to be fired. The body of the completion handler HandleRetrieveCompleted, which is not shown, would call Set() on the ManualResetEvent (passed in as the UserState object).

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

}
+2  A: 

You don't - an event is like a property, it's just syntactic sugar around a pair of methods (add/remove instead of the get/set for a property). F# actually does expose events as first class citizens, but C# doesn't :(

There are a few options though:

  • Pass in an "event subscriber" delegate that you call with the new handler you want to add (and potentially an event unsubscriber delegate too). Something like this:

    new Receiver(handler => button.Click += handler, ...)
    
  • Pass in an EventInfo and subscribe with reflection (urgh)

  • Look into the Reactive Extensions framework, which has various ways of working with events (using reflection, but it means Microsoft does the reflection work rather than you :)

We could give better advice if we knew the bigger picture - care to inform us more?

EDIT: Okay, so in this case you'd need to pass in both the subscription and unsubscription code:

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

That's pretty nasty, admittedly. You may well find there's something nicer in Reactive Extensions, but that would at least work...

Jon Skeet
I've edited the question to give more context of what I am trying to achieve.
Phillip Ngan