Firing events via reflection is always going to be dodgy as heck. In
particular, you have know way of knowing what the backer is. Is *might* be a
compiler-built field, but it might be a separate field I provide (perhaps
through a facade to an encapsulated class), or it might be via an
EventHandlerList, or about 17 other things. So you can't rely on reflection
to work unless you know what class you are dealing with and how the event is
implemented.
Even within a class you own, this would mandate some kind of switch or
dictionary; as a thought, it would be quite easy to create a variant of
EventHandlerList that works on Dictionary<string, EventHandler>, and lets
you do all of this just using the handler (string) directly as the key...
i.e. something like below...
But as a general principal, events should be fired from *within* a class,
not from outside.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
public class MyData
{
public event EventHandler SomeEvent1 {
add { events.Add("SomeEvent1", value); }
remove { events.Remove("SomeEvent1", value); }
}
private readonly DelegateDictionary events = new DelegateDictionary();
public event EventHandler SomeEvent2
{
add { events.Add("SomeEvent2", value); }
remove { events.Remove("SomeEvent2", value); }
}
public event EventHandler SomeEvent3
{
add { events.Add("SomeEvent3", value); }
remove{ events.Remove("SomeEvent3", value); }
}
public void FireEvent(string name)
{
events.InvokeHandler(name, this);
}
}
class Program
{
static void Main()
{
MyData data = new MyData();
data.SomeEvent1 += new EventHandler(data_SomeEvent1);
data.SomeEvent2 += new EventHandler(data_SomeEvent2);
data.SomeEvent2 += new EventHandler(data_SomeEvent2);
data.FireEvent("SomeEvent2");
data.FireEvent("SomeEvent1");
data.FireEvent("SomeEvent3");// not subscribed
data.FireEvent("SomeDuffEvent");
}
static void data_SomeEvent1(object sender, EventArgs e)
{
Debug.WriteLine("data_SomeEvent1");
}
static void data_SomeEvent2(object sender, EventArgs e)
{
Debug.WriteLine("data_SomeEvent2");
}
}
public class DelegateDictionary
{
private readonly Dictionary<string, Delegatedata = new
Dictionary<string, Delegate>();
public void InvokeHandler(string key, object sender)
{
EventHandler handler = GetHandler(key);
if (handler != null) handler(sender, EventArgs.Empty);
}
public void Invoke(string key, params object[] parameters)
{
Delegate handler = this[key];
if (handler != null) handler.DynamicInvoke(parameters);
}
public EventHandler GetHandler(string key)
{
return (EventHandler) this[key];
}
public T Get<T>(string key)
{
return (T)(object)this[key];
}
public Delegate Get(string key)
{
return this[key];
}
public void Add(string key, Delegate handler)
{
if (handler == null) return;
Delegate current;
if (data.TryGetValue(key, out current))
{
data[key] = Delegate.Combine(current,handler);
}
else
{
data.Add(key, handler);
}
}
public void Remove(string key, Delegate handler)
{
if (handler == null) return;
Delegate current;
if (data.TryGetValue(key, out current))
{
data[key] = Delegate.Remove(current, handler);
}
}
public Delegate this[string key]
{
get
{
Delegate handler;
data.TryGetValue(key, out handler);
return handler;
}
}
}