2010-07-11 56 views
5

我有這樣的代碼:如何在函數調用時自動調用事件?

public class Foo 
{ 
    public SomeHandler OnBar; 

    public virtual void Bar() 
    { 
    } 
} 

foo是一個基類,爲此其他類可能繼承它。
我想在調用Bar()時總是會觸發OnBar事件,即使它沒有在Bar中顯式調用。
怎麼辦?

回答

9

一個常見的模式是有一個非虛擬的方法,將做你想要的,調用虛擬方法。子類可以重寫內部方法來改變功能,但公共方法可以是非虛擬的,總是首先引發事件。

public class Foo 
{ 
    public SomeHandler OnBar; 

    public void Bar() 
    { 
     if (OnBar != null) 
     { 
      OnBar(this, EventArgs.Empty); 
     } 
     BarImpl(); 
    } 

    protected virtual void BarImpl() 
    { 
    } 
} 
+0

基本上模板方法模式的實現+ 1 – DanP 2010-07-11 15:07:45

+0

所以這是最好的方法?在C++中,我將使用bind()從事件調用函數和原始函數中創建一個新函數。 – 2010-07-11 15:18:14

2

簡答:你不能。不是微軟爲您提供的開箱即用功能。

這就是說,看看.NET中的「面向方面的編程」。谷歌,你可能會得到一些有用的東西。

加入:標準方法是在Bar()方法中引發事件,然後要求所有派生類調用基本實現。但是你不能執行它。

1

首先您提供的代碼不會編譯。
虛擬功能必須有一個主體。

爲了確保事件被解僱,你可以這樣做。

public class Foo 
{ 
    public SomeHandler OnBar; 

    public void Bar() 
    { 
    OnBar(); (check for nulls) 
    ProtectedBar(); 
    } 

    protected virtual ProtectedBar() 
    { 
    } 
} 
+0

你是對的。然而,在這種情況下這並不重要。這只是爲了證明該功能可以被覆蓋。我不知道你爲什麼被低估。我致力於平衡。 – 2010-07-11 15:11:32

+1

您提供的代碼不會編譯 - 您的虛擬函數沒有返回類型,您的評論也不是評論。 – 2010-07-11 15:14:29

+0

我想有些徽章收藏家低估了我的徽章。 :) – 2010-07-11 15:14:37

0

正如Vilx-說,我想更好的辦法做這樣的東西是使用面向方面的編程。

這會幫助你解決「糾纏的代碼」(即在一個不應該有這個責任的方法中調用一個事件)和「分散代碼」(即在很多方法中調用同一個事件,複製你的代碼)問題。

你應該看看postsharp,它有一個免費的社區版。

相關問題