使用反射调用匿名事件处理程序

本文关键字:事件处理 程序 调用 反射 | 更新日期: 2023-09-27 18:04:56

我已经为客户端-服务器UI框架实现了我自己的事件注册,就像在ASP.NET中一样。我存储事件的名称(例如:"Click"),作为我记得的值

oEventHandler.Method.DeclaringType.AssemblyQualifiedName.ToString() + "." + oEventHandler.Method.Name.

然后,为了稍后重新调用事件处理程序,我重新创建委托:

var oEventHandler = Delegate.CreateDelegate( typeof( BLUIEventHandler ), oPage, sEventMethod, false )

并在页面上调用它:

oEventHandler.Invoke( oPage, this, oEventArgs );

对于作为ASPX页面一部分的事件处理程序(如

)可以正常工作。
var oTheButton = new UIButton();
oTheButton.Click += this.HandleClick;
private void HandleClick() {}

但匿名委托失败:

var oTheButton = new UIButton();
oTheButton.Click += delegate {/* Will never be called. */};
非匿名委托的结果字符串为:
"MyTest.Rene.UI.Foo, BDRS, Version=8.10.1.19703, Culture=neutral, PublicKeyToken=null.HandleClick"

对于匿名委托,它是:

"MyTest.Rene.UI.Foo+<>c__DisplayClass1, MyTest, Version=8.10.1.17866, Culture=neutral, PublicKeyToken=null.<OnInitializeLayout>oTheButton__0"

然而,当我尝试重新创建匿名委托时,我得到一个绑定错误。是否有一种方法可以回到匿名委托并调用它?

使用反射调用匿名事件处理程序

这在匿名方法的一般情况下是行不通的,因为非常有可能涉及到捕获的变量,并且您将不知道要捕获的值(另外您已经改变了性质:原始闭包可以更新捕获的变量 -它们不是孤立的副本)。

我个人认为应该存储Delegate实例,而不是名称。EventHandlerList是一种典型的实现方式(每个事件都有唯一的object键)。