首页 > 后端开发 > C++ > C# 中的事件处理程序可以在运行时被窃取和重新分配吗?

C# 中的事件处理程序可以在运行时被窃取和重新分配吗?

Barbara Streisand
发布: 2024-12-30 21:06:09
原创
324 人浏览过

Can Event Handlers Be Stolen and Reassigned at Runtime in C#?

窃取事件处理程序:运行时奥德赛

简介:

在软件开发中,有时可能需要从一个控件分配一个事件处理程序在运行时到另一个。本文深入探讨了此类操作的可行性,探讨了潜在的注意事项和可用的解决方法。

原始问题:

原始问题试图找到一种方法来传输分配的事件处理程序在运行时从一个按钮 (btn1) 到另一个按钮 (btn2)。然而,编译器认为这个赋值无效,指出事件处理程序只能分配到赋值的左侧。

解决方案:

虽然直接的方法遇到了编译器错误事实证明,在运行时窃取事件处理程序确实是可能的,尽管有一个警告:需要反射。反射授予对对象的私有和内部成员的访问权限,这些成员通常是不可访问的。

实现细节:

解决方案涉及几个步骤:

  1. 检索秘密事件密钥: 事件处理程序使用名为“EventClick”的私有字段在内部存储。反射用于静态访问此字段。
  2. 获取EventHandlerList: Component 类的“Events”属性存储包含所有已注册事件处理程序的EventHandlerList。该属性通过反射访问。
  3. 从源中删除处理程序:使用 EventHandlerList,可以从源控件 (btn1) 中删除事件处理程序。
  4. 将处理程序添加到目标: 然后使用相同的 EventHandlerList 将事件处理程序添加到目标控件(btn2).

示例代码:

以下代码演示了事件窃取技术:

using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Reflection;

namespace WindowsFormsApplication1 {
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
      button1.Click += new EventHandler(button1_Click);
      // Get secret click event key
      FieldInfo eventClick = typeof(Control).GetField("EventClick", BindingFlags.NonPublic | BindingFlags.Static);
      object secret = eventClick.GetValue(null);
      // Retrieve the click event
      PropertyInfo eventsProp = typeof(Component).GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance);
      EventHandlerList events = (EventHandlerList)eventsProp.GetValue(button1, null);
      Delegate click = events[secret];
      // Remove it from button1, add it to button2
      events.RemoveHandler(secret, click);
      events = (EventHandlerList)eventsProp.GetValue(button2, null);
      events.AddHandler(secret, click);
    }

    void button1_Click(object sender, EventArgs e) {
      MessageBox.Show("Yada");
    }
  }
}
登录后复制

警告:

As代码表明,窃取事件处理程序的过程相当复杂,需要对内部对象结构有复杂的了解。很明显,微软已经做出了巨大的努力来阻止直接访问这些结构,这表明应该明智地使用这项技术。

以上是C# 中的事件处理程序可以在运行时被窃取和重新分配吗?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板