简体   繁体   中英

Determine event name from EventHandler<T> in C#

My question is if I can determine an event's name passed through a parameter with EventHandler type? With some code it becomes more clear:

public void RaiseEvent<T>(EventHandler<T> eventToRaise, T args) where T : EventArgs, IXmlConvertable
    {
        Log(eventToRaise.Method.Name, args.ToXElement());
        ThreadPool.QueueUserWorkItem((e) => eventToRaise(this, args));
    }

public event EventHandler<ProductLeftEventArgs> ProductLeftEvent = delegate { };

As you can see I want to create a method that not only calls the event async, but also logs the action. IXmlConvertable is a custom interface, which is used for logging. I call the method like this:

this.RaiseEvent(this.ProductLeftEvent, new ProductLeftEventArgs() { ... });

What I would like to gain is a string with "ProductLeftEvent". Unfortunately the eventToRaise.Method.Name gives the string "DeliverEvent". Do you think it is possible to achieve this name? It also worth mention, that I use weak event manager when I assing a handler.

eventToRise parameter is a delegate - ie reference to a method (and a target or object on which this method should be called). Event holds a reference to all methods that were subscribed to that event.

So in your case it seems that "DeliverEvent" is the method that was attached to your event in some other part of the application like this: someObject.ProductLeftEvent += this.DeliverEvent;

If you really want to pass event itself to the RaiseEvent method you either need to use expressions or simply pass an eventName (but this will be a kind of duplication).

Below is an example of how to use expressions to do this:

public void RaiseEvent<T>(Expression<Func<EventHandler<T>>> eventToRaise, T args) where T : EventArgs, IXmlConvertable
{
    string eventName = ((MemberExpression)eventToRaise.Body).Member.Name;
    Log(eventName, args.ToXElement());
    EventHandler<T> eventHandler = eventToRaise.Compile()();
    ThreadPool.QueueUserWorkItem((e) => eventHandler(this, args));
}

You will call this method like this:

this.RaiseEvent(() => this.ProductLeftEvent, new ProductLeftEventArgs() { ... });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM