c# - 当我在派生类中时,如何 "unbind"附加到基类中事件的事件处理程序?

标签 c# event-handling

我曾经遇到过一种情况,我不得不重写我的某个派生类中的事件处理程序。不幸的是,我不能只是“覆盖”它,因为实现逻辑严格绑定(bind)到基类中的特定方法实现。

我的自然想法是首先从事件中“解除绑定(bind)”原始事件处理程序,然后再绑定(bind)我自己的全新方法。所以我尝试像这样使用“-=”运算符:

myObject.SomeEvent -= new EventHandler (BaseClass.SomeEventHandler)

此时编译器提示它无法访问私有(private)方法 SomeEventHandler。由于基类是库的一部分,我真的不想修改它的实现(尽管看起来很简单,只是将“私有(private)”变成“ protected ”);

将事件处理程序附加到事件非常简单。为什么摆脱一个如此困难?

为什么我想要它?因为基本实现存在一些问题(只是没有处理我们的特殊情况)所以我想重新定义它。但即使在我附加了我的事件处理程序之后,基本实现仍然会被执行。由于它正在进行某种重定向,我自己的实现永远不会运行,因为请求处理在重定向后在服务器上被破坏。

有没有办法在不修改其实现的情况下从库中删除基类中的事件处理程序?

最佳答案

如果您的代码可以正式看到处理程序,摆脱处理程序同样容易。。如果绝对必要,可以使用反射取消订阅以获取委托(delegate),但这很麻烦。这将是一个 很多 更清洁和更安全的方法:a:避免要求,或 b:更改代码以使处理程序 protected


反射(reflection)方法(使用风险自负);取消注释 Bar.ctor() 中的 block 以查看更改。

using System;
class Foo
{
    public event EventHandler SomeEvent;
    public Foo()
    {
        SomeEvent += SecretHandler; // a bad idea, anyway
                                    //(self-subscribed events....)
    }
    protected virtual void OnSomeEvent()
    {
        EventHandler handler = SomeEvent;
        if (handler != null) handler(this, EventArgs.Empty);
    }
    private void SecretHandler(object sender, EventArgs args)
    {
        Console.WriteLine("suscribed");
    }
}
class Bar : Foo
{
    public Bar()
    {
        /*
        MethodInfo method = typeof(Foo).GetMethod("SecretHandler",
            BindingFlags.NonPublic | BindingFlags.Instance);
        EventHandler handler = (EventHandler)Delegate.CreateDelegate(
            typeof(EventHandler), this, method);
        SomeEvent -= handler;
         */
    }
    public void Test()
    {
        OnSomeEvent();
    }
}
static class Program
{
    static void Main()
    {
        Bar bar = new Bar();
        bar.Test();
    }
}

关于c# - 当我在派生类中时,如何 "unbind"附加到基类中事件的事件处理程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/714189/

相关文章:

c# - 如何使用 .NET 获取位于两个 '{' 括号'}' 之间的文本字符串?

c# - int.Parse 在 C# 中使用装箱/拆箱或类型转换吗?

javascript - 如何在事件中或手动启动 CKeditor 插件?

java - 如何在接受下一个 MouseEvent 之前等待当前 MouseEvent EventHandler 结束?

c# - 如何使 DataGrid 列随着控件宽度的变化而拉伸(stretch)?

c# - 无论如何,是否有 DllImport 函数从作为字节数组加载到 RAM 中的 native dll?

c# - 在 3 层设置中在哪里可以找到自定义成员资格、角色、配置文件提供程序?

c# - MouseEventHandler 附加参数 - 无法定义 "sender"和 "e"

javascript - 模仿 jQuery 的 .click() 的 native JavaScript 方法

javascript - 在顺序很重要的 jQuery 中处理多次单击事件