C# Create a Delegate that fires an event?
Is it possible to use Reflection is C# to fire an event? Say I have a situation like this:
public delegate void SomeEventHandler(object sender, BenArgs e);
class EventHub
{
public event SomeEventHandler SOME_EVENT;
public void fireEvent(String eventName)
{
SomeEventHandler evt = (SomeEventHandler) Delegate.CreateDelegate(typeof(SomeEventHandler), this, eventName);
evt.Invoke(null, null);
}
}
Meaning if I call
EventHub.fireEvent("SOME_EVENT")
then it makes the event hub fire SOME_EVENT? I've tried this and am just getting exceptions.
This is mostly a curiosity of mine, I know that in this 开发者_开发技巧case I could just as easily fire the event without reflection.
Assuming your current scenario, i.e.:
- A field-like event.
- The backing delegate-field has the same name as the event.
(this, EventArgs.Empty)
are valid arguments to pass to the delegate.
You can do something like this (more argument validation required):
public void fireEvent(String eventName)
{
// Get a reference to the backing field
var del = (Delegate)typeof(EventHub)
.GetField(eventName, BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(this);
// Invoke the delegate, it's invocation-list will contain the listeners
if(del != null)
del.DynamicInvoke(this, EventArgs.Empty);
}
Usage:
var eHub = new EventHub();
eHub.SOME_EVENT += delegate { Console.WriteLine("SOME_EVENT fired.."); };
eHub.fireEvent("SOME_EVENT");
Now, you can generalize this idea with an extension method on object
if you like, but all of this is a really bad idea. This problem can't be solved in the general case because one can't know how an event is "implemented." There could be arbitrary code inside the add
and remove
methods, and the logic to "fire" the event could also be just about anything. There might not even be a backing multicast delgate field to store the listeners.
In any case, trying to tell an object to fire an event is almost always a sign of a major design-flaw, IMO. If you still really do want this, it would be much better to declare a method like this in your class:
public void RaiseXXXEvent() { ... }
精彩评论