devdigital
devdigital

Reputation: 34349

Assign event handlers to an object instance at runtime in a generic way

I'm trying to create a generic method which assigns (and deassigns) an event handler to an object instance's event at runtime.

Something like:

private void MyMethod<TEventArgs>(...)
   where TEventArgs : EventArgs
{
   EventHandler<TEventArgs> eventHandler = (s, e) =>
   {
      // logic
   }

   // want to assign eventHandler to an object instance passed into this method

   // more logic

   // want to deassign eventHandler from object instance
}

Currently, I'm passing in an assignEvent and deassignEvent delegate, something like:

private void MyMethod<TEventArgs>(Action<EventHandler<TEventArgs>> assignEvent, Action<EventHandler<TEventArgs>> deassignEvent)
{
   EventHandler<TEventArgs> eventHandler = (s, e) =>
   {
      // logic
   }

   assignEvent(eventHandler);

   // more logic

   deassignEvent(eventHandler);
}

And then calling the method like so:

var myObject = new MyObject();
MyMethod<MyEventArgs>(e => myObject.MyEvent += e, e => myObject.MyEvent -= e);

This just seems really horrible though!

What other options do I have?

Upvotes: 2

Views: 392

Answers (2)

Adam Robinson
Adam Robinson

Reputation: 185643

Unfortunately, there's not a much cleaner option. Events, despite being usable within the declaring class as an ordinary delegate member, are not publicly exposed as delegates. The event keyword means that it exposes add and remove functionality, but nothing else. In other words, you can't just pass myObject.MyEvent to MyMethod (unless you were to expose the actual delegate, which is a bad idea).

Upvotes: 1

Reed Copsey
Reed Copsey

Reputation: 564433

A potentially better option here is to convert this to an IObservable<T>, via using Observable.FromEvent (in the Rx Framework). This allows you to treat the event itself in a first class manner, pass it into your method, then Dispose() the subscription at the end.

Upvotes: 2

Related Questions