我有這樣的代碼:如何在函數調用時自動調用事件?
public class Foo
{
public SomeHandler OnBar;
public virtual void Bar()
{
}
}
foo是一個基類,爲此其他類可能繼承它。
我想在調用Bar()
時總是會觸發OnBar
事件,即使它沒有在Bar中顯式調用。
怎麼辦?
我有這樣的代碼:如何在函數調用時自動調用事件?
public class Foo
{
public SomeHandler OnBar;
public virtual void Bar()
{
}
}
foo是一個基類,爲此其他類可能繼承它。
我想在調用Bar()
時總是會觸發OnBar
事件,即使它沒有在Bar中顯式調用。
怎麼辦?
一個常見的模式是有一個非虛擬的方法,將做你想要的,調用虛擬方法。子類可以重寫內部方法來改變功能,但公共方法可以是非虛擬的,總是首先引發事件。
public class Foo
{
public SomeHandler OnBar;
public void Bar()
{
if (OnBar != null)
{
OnBar(this, EventArgs.Empty);
}
BarImpl();
}
protected virtual void BarImpl()
{
}
}
簡答:你不能。不是微軟爲您提供的開箱即用功能。
這就是說,看看.NET中的「面向方面的編程」。谷歌,你可能會得到一些有用的東西。
加入:標準方法是在Bar()
方法中引發事件,然後要求所有派生類調用基本實現。但是你不能執行它。
首先您提供的代碼不會編譯。
虛擬功能必須有一個主體。
爲了確保事件被解僱,你可以這樣做。
public class Foo
{
public SomeHandler OnBar;
public void Bar()
{
OnBar(); (check for nulls)
ProtectedBar();
}
protected virtual ProtectedBar()
{
}
}
你是對的。然而,在這種情況下這並不重要。這只是爲了證明該功能可以被覆蓋。我不知道你爲什麼被低估。我致力於平衡。 – 2010-07-11 15:11:32
您提供的代碼不會編譯 - 您的虛擬函數沒有返回類型,您的評論也不是評論。 – 2010-07-11 15:14:29
我想有些徽章收藏家低估了我的徽章。 :) – 2010-07-11 15:14:37
正如Vilx-說,我想更好的辦法做這樣的東西是使用面向方面的編程。
這會幫助你解決「糾纏的代碼」(即在一個不應該有這個責任的方法中調用一個事件)和「分散代碼」(即在很多方法中調用同一個事件,複製你的代碼)問題。
你應該看看postsharp,它有一個免費的社區版。
基本上模板方法模式的實現+ 1 – DanP 2010-07-11 15:07:45
所以這是最好的方法?在C++中,我將使用bind()從事件調用函數和原始函數中創建一個新函數。 – 2010-07-11 15:18:14