是否可以在lambda表达式中定位EventHandler?

举一个简单的例子,如果我有某种按钮UI类,我是否可以编写一个函数来获取指向其Click事件处理程序的表达式:

 SomeMethod(button => button.Click); 

我正在尝试消除当前用于系统的一些魔术字符串以使事件等待。 有问题的代码来自Frank Krueger撰写的博客文章 (如果你想要一些背景,那么值得一读)。

 public static Task GetEventAsync(this object eventSource, string eventName) where TEventArgs : EventArgs { //... Type type = eventSource.GetType(); EventInfo ev = type.GetEvent(eventName); //... } 

虽然内部的细节可能并不重要,但完整的方法允许您使用Event触发作为Task的完成源,使得使用await更容易管理。 对于某个引发事件的类,您可以通过简单的调用将该事件绑定到Task

 Task eventTask = someEventCausingObject.GetEventAsync("SomeEventHandler"); // traditionally used as someEventCausingObject.SomeEventHandler += ...; await eventTask; // Proceed back here when SomeEventHandler event is raised. 

我一直在愉快地使用这个项目,但它有它的缺点,其中最大的一个是使用硬编码的事件名string s。 这使得事件名称更改变为运行时exception,并且难以确定事件的使用。

我开始尝试创建一个允许EventHandler作为Expression一部分传入的版本,其目标是这样的:

 await someEventCausingObject.GetEventAsync(x => x.SomeEventHandler); 

…用相应的方法签名……

 public static Task GetEventAsync(this TSource eventSource, Expression<Func> eventHandlerExpression) where TEventArgs : EventArgs { //... } 

不幸的是,调用代码中的lambda表达式导致编译错误:

 Error CS0070: The event `SomeEventHandler' can only appear on the left hand side of += or -= when used outside of the type `EventCausingClass'. 

考虑到事件处理程序的使用方式,这有一定意义,但我希望找到比预先指定的字符串名称更好的解决方案。 似乎搜索“表达式”和“事件处理程序”的组合都会被描述为开始+=事件处理程序赋值的lambda表达式的人所污染。 我希望我在这里遗漏一些明显的东西。

不,无法定位事件。 基本上事件不是真正的类型成员,而只是C#语法,它产生add_EventName和remove_EventName方法对。

您可以尝试参考这些内部方法名称,但在C#中不可能 – http://msdn.microsoft.com/en-us/library/z47a7kdw.aspx

SO中有许多类似的问题,答案是否定的 – 就像Jon Skeet的这个问题一样https://stackoverflow.com/a/4756021/2170171

如果你真的很疯狂,你可以尝试类似的东西

 private static void Subscribe(Action addHandler) { var IL = addHandler.Method.GetMethodBody().GetILAsByteArray(); // Magic here, in which we understand ClassName and EventName ??? } 

用法如

 Subscribe(() => new Button().Click += null); 

您可以尝试使用Cecil http://www.mono-project.com/Cecil来分析IL,或者实现您自己的逻辑,因为它对于可预测的代码行来说应该不会太难。

我不认为这是一个很好的解决方案,因为它只是用另一个(正确的Subscribe调用)取代了一个头痛(正确的事件命名)。 虽然,它将有助于重命名的东西。