堆積控制項不等於會寫視窗程式,正如砌磚不等於是建築師。真正的關鍵在於理解程式結構——特別是事件從何而來,事件觸發與事件處理之間的連結機制。本文將帶你拆解視窗體與控制項的關係,從 C++ 回呼函數演進到 C# 委派,再到事件模型的誕生。
class B { void Method(A arg) { arg.Method(); } } // B 緊密依賴 A
結構簡單,但類別間綁死,彈性極差。
因函數指標無法指向成員函數,需引入「跳板函數」:
typedef void (*FunctionPointer)();
class B { FunctionPointer funPointer; void Method() { funPointer(); } }
void Function() { A a; a.Method(); } // 跳板
b.funPointer = Function; b.Method(); // 主調→跳板→被調
雖解耦,但指標不安全,易導致崩潰與記憶體洩漏。
C# 摒棄指標,引入 委派。委派是類別,其實例才像函數指標。委派實例優勢:
+= 串聯多個方法,一次觸發全執行。delegate void MyDelegate();
class B { public MyDelegate deleInstance;
public void Method() { if (deleInstance != null) deleInstance(); } }
static void Function() { new A().Method("Tim"); }
b.deleInstance += new MyDelegate(Function); b.Method();
若類別 A 有數百個簽名各異的方法,B 類別豈非要宣告數百個委派?更何況 A、B 可能由不同團隊開發。跳板函數(或匿名方法/Lambda)統一介面,才是工程實踐的正解。
程式碼上,事件只是在委派前加上 event 關鍵字;但邏輯上,它完成了從「機制」到「意圖」的躍升——封裝發布/訂閱模式,限制外部只能 +=/-=,不能直接呼叫或覆寫。這一小步,卻是架構設計的一大步。
下一篇將深入剖析視窗體事件模型的完整運作流程,敬請關注《深入淺出視窗體(二)——視窗體事件模型(下)》。
法律聲明:轉載請保持完整,註明出處 BKJIA 及作者 劉鐵猛(博客連結),發送郵件至 no_sound@hotmail.com。原文出處:上善若水 潤物無聲。