首頁 >後端開發 >C++ >C# 中的事件處理程序可以在執行時被竊取和重新指派嗎?

C# 中的事件處理程序可以在執行時被竊取和重新指派嗎?

Barbara Streisand
Barbara Streisand原創
2024-12-30 21:06:09324瀏覽

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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn