I have a MulticastDelegate
that can reference one of a number of (legacy) delegates that have the same signature. For example:
public delegate void ObjectCreated(object sender, EventArgs args);
public delegate void ObjectDeleted(object sender, EventArgs args);
//...
Those delegates are then used to define events:
public event ObjectCreated ObjectWasCreated;
public event ObjectDeleted ObjectWasDeleted;
I then have a method which takes in a MulticastDelegate
that I use to do some common checking:
void DispatchEvent(MulticastDelegate handler, object sender, EventArgs args)
{
if (handler != null)
{
// ...
handler.DynamicInvoke(sender, args);
}
}
Which is called from within other methods of the class wherein the events were defined:
DispatchEvent(ObjectWasCreated, sender, args);
DispatchEvent(ObjectWasDeleted, sender, args);
Is there a more concise way to do this that avoids DynamicInvoke?
Here's my reflection-free solution. It basically implements a multicast delegate as a list. Less code? No. Better performance? I don't know. Cleaner? Meh.
public delegate void ObjectCreated(object sender, EventArgs args);
public delegate void ObjectDeleted(object sender, EventArgs args);
public event ObjectCreated ObjectWasCreated
{
add
{
m_ObjectCreatedSubscribers.Add(value.Invoke);
}
remove
{
m_ObjectCreatedSubscribers.RemoveAll(e => e.Target.Equals(value));
}
}
public event ObjectDeleted ObjectWasDeleted
{
add
{
m_ObjectDeletedSubscribers.Add(value.Invoke);
}
remove
{
m_ObjectDeletedSubscribers.RemoveAll(e => e.Target.Equals(value));
}
}
private List<Action<object, EventArgs>> m_ObjectCreatedSubscribers = new List<Action<object, EventArgs>>();
private List<Action<object, EventArgs>> m_ObjectDeletedSubscribers = new List<Action<object, EventArgs>>();
void DispatchEvent(List<Action<object, EventArgs>> subscribers, object sender, EventArgs args)
{
foreach (var subscriber in subscribers)
subscriber(sender, args);
}