从 C# 中的 EventHandler<T> 确定事件名称

Determine event name from EventHandler<T> in C#

我的问题是我是否可以确定通过 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"。你认为有可能实现这个名字吗?还值得一提的是,我在分配处理程序时使用弱事件管理器。

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() { ... });