Determine event name from EventHandler<T> in C#

本文关键字:gt in event lt from EventHandler Determine name | 更新日期: 2023-09-27 18:16:00

我的问题是,如果我能确定一个事件的名称通过参数与EventHandler类型?通过一些代码,它变得更加清晰:

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 { };

正如您所看到的,我想创建一个方法,它不仅异步调用事件,而且记录操作。IXmlConvertable是一个自定义接口,用于记录日志。我这样调用这个方法:

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

我想获得的是一个字符串"ProductLeftEvent"。不幸的是,eventToRaise.Method.Name给出了字符串"DeliverEvent"。你认为这个名字有可能实现吗?还值得一提的是,我在传递处理程序时使用弱事件管理器。

Determine event name from EventHandler<T> in C#

eventToRise参数是一个委托-即对方法的引用(以及应该调用该方法的目标或对象)。事件保存对订阅该事件的所有方法的引用。

所以在你的情况下,"DeliverEvent"似乎是在应用程序的其他部分附加到你的事件的方法,像这样:someObject.ProductLeftEvent += this.DeliverEvent;

如果你真的想把事件本身传递给RaiseEvent方法,你要么需要使用表达式,要么简单地传递一个eventName(但这将是一种重复)。

下面是如何使用表达式来完成此操作的示例:

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));
}

你将像这样调用这个方法:

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