2009-02-11 106 views
3

這是處理事件.NET中的首選/推薦方式:C#中事件處理的首選方法是什麼?

this.Load += new EventHandler(Form1_Load); 
private void Form1_Load(object sender, EventArgs e) 
{ } 

protected override void OnLoad(EventArgs e) 
{ 
    base.OnLoad(e); 
} 

什麼將每種方法的優點/缺點是什麼?多年來我一直使用這兩種方法,並且通常更傾向於第一種方法,因爲這是Visual Studio爲處理事件而自動創建的。第二種方法對我有什麼缺點嗎?

回答

8

第一種方式是Microsoft建議的。該模式是:

  1. 一些代碼,希望引發一個事件,呼籲OnXxx
  2. OnXxx進行調用以委託
  3. 有線調用事件處理程序

如果執行第二個模型,你可能會忘記base.OnXxx的呼叫並破壞一切。選項2的好處在於,您可以決定是在所有其他事件處理程序之前還是之後調用它。如果你把你的代碼放在base.OnXxx之前,你會在事件發生之前執行。當然,第一個模型總是可以使用的,第二個模型只有在你提升事件的子類的時候。

-1

重寫的方法是可取的,因爲它實際上將由CLR以多態方式調用

[編輯]這是爲什麼我認爲重寫的方法是可取:

下面是一個簡單的例子:

class Foo 
{ 
    public event EventHandler Changed = delegate { }; 

    protected virtual void OnChanged() 
    { 
     this.Changed(this, EventArgs.Empty); 
    } 
} 

class Bar : Foo 
{ 
    public Bar() 
    { 
     this.Changed += new EventHandler(this.Bar_Changed); 
    } 

    void Bar_Changed(Object sender, EventArgs e) { } 
} 

class Baz : Foo 
{ 
    protected override void OnChanged() 
    { 
     base.OnChanged(); 
    } 
} 

現在我相信了Baz是更好地執行,這裏是爲什麼。 Bar必須做到以下幾點IL指令線了一個事件:

L_000a: ldftn instance void Bar::Bar_Changed(object, class [mscorlib]System.EventArgs) 
    L_0010: newobj instance void [mscorlib]System.EventHandler::.ctor(object, native int) 
    L_0015: call instance void Foo::add_Changed(class [mscorlib]System.EventHandler) 

我們必須創建一個委託處理方法,該EventHandler的一個實例,然後調用add_Changed方法在基類中的事件。雖然這些不是性能殺手,但Baz無法運行以前的代碼。由於任何對OnChanged的調用都是虛擬的,唯一的性能損失是CLR在繼承鏈中找到調用正確的實例方法。

+0

你能否再解釋一下 - 我不確定我明白你的意思。 – 2009-02-11 16:27:06

5

這完全取決於您想要抓住事件的原因以及原因。

第一種方法(接線)用於當您需要某些其他類來處理事件。你可能需要這樣做的原因有很多,另一個類可以訪問執行一些複雜邏輯或其他任何事情的服務。重點在於,如果您希望單獨的觀察員響應該事件,則使用第一種方法。

第二種方法(重寫)用於當您希望表單響應,因爲它可以;因爲它是本地的責任。

+0

好點,我忘了其他處理事件的其他事情。在表單處理它自己的事件的情況下,爲什麼VS連接事件處理程序而不是使用保護覆蓋? – 2009-02-11 16:23:33

+0

你必須問MS有關這個決定。我不老實地知道。 – 2009-02-11 16:28:17

1

雖然不是原來的問題,我想指出的是:

this.Load += new EventHandler(Form1_Load); 

可以寫爲:

this.Load += Form1_Load; 

委託建設推斷。

0

快速規則並不困難,但這兩種方法都存在問題。你選擇一個你可以輕鬆避免的。

代表

很多開發商放置+ =​​代碼在一個地方,它可以反覆地叫。至少很多新手都這樣做。因此,所有者控制所維護的委託列表中將有'n'個條目,並且所有這些條目都會被調用。簡單的避免方法是將+ =調用放在只被調用一次的構造函數中。

OnXXXX

風險是忘記調用base.XXX方法。這是錯誤的常見來源,大多數Windows程序員都知道如果您錯過調用基類版本的問題 - 這對於Windows消息(繪圖等)尤其如此。

相關問題