JBRWilkinson
JBRWilkinson

Reputation: 4855

C# 2.0 Dynamic Event Subscription with known event signature

Similarly to this question:

C# Dynamic Event Subscription

I would like to be able to wire up an event handler to an event fired out of a dynamically-created object. I am doing this to verify that my JavaScript and other non-.NET code is able to connect to the objects' events.

My event signature in the object is:

delegate void MediaItemFellbackDelegate(int id, string name, string path);

Here is my 'DynamicHost' code:

public delegate void MediaItemFellbackDelegate(int id, string name, string path);

public void MediaItemFellback(int id, string name, string path)
{
}


private void HandleEvent(string eventName, Delegate handler)
{
  try
  {
    BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
    EventInfo mediaItemFellback = m_PlayerType.GetEvent(eventName, bindingFlags);
    mediaItemFellback.AddEventHandler(m_Player, handler);
  }
  catch (Exception ex)
  {
    MessageBox.Show(ex.ToString());
  }
}

HandleEvent("MediaItemFellback", new MediaItemFellbackDelegate(this.MediaItemFellback));

but I end up with the exception:

Object of type 'DynamicHost.Main+MediaItemFellbackDelegate' cannot be converted to type 'Player.MediaItemFellbackDelegate'.

in the AddEventHandler() call.

Of course, they are different types, but the signatures are identical.

What's going wrong here?

Upvotes: 3

Views: 629

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1500225

Quite simply, you can't subscribe to an event using the wrong kind of delegate.

What you could do is create the right kind of delegate in HandleEvent:

private void HandleEvent(string eventName, Delegate handler)
{
  try
  {
    BindingFlags bindingFlags = BindingFlags.Instance | 
                                BindingFlags.Public | BindingFlags.NonPublic;
    EventInfo mediaItemFellback = m_PlayerType.GetEvent(eventName, bindingFlags);
    Delegate correctHandler = Delegate.CreateDelegate(
        mediaItemFellback.EventHandlerType, handler.Target, handler.Method);
    mediaItemFellback.AddEventHandler(m_Player, correctHandler);
  }
  catch (Exception ex)
  {
    MessageBox.Show(ex.ToString());
  }
}

Upvotes: 3

Related Questions