2011-02-28 86 views
1

非常基本的問題,所以我只是尋找最佳實踐。C#最佳實踐 - 事件訂閱

我的班級有幾個應該訂閱的活動。 (例如DiscoveryCompleted)。在方法中,我會檢查事件是否爲null,但是我不確定是否應該引發異常,如果是的話。 NotImpletementedException?

如果異常未處理,它看起來不很優雅。

您的想法?

回答

3

我認爲這正是NotImplementedException的創建目的。你絕對不應該在生產代碼中遇到NotImplementedException,但是它在測試過程中會讓你痛苦地清楚你的代碼路徑有沒有被實現。

有點像一個TODO註釋,但多在你面前:)

雖然,我可能會質疑是否有一個事件處理程序,必須預訂,並沒有默認的用戶,並不表示一個設計問題。

編輯

我想我誤解了你最初的問題咯,根據您的評論。正如其他人所說(我質疑),當你沒有一個事件處理程序的訂閱者時,你不應該拋出異常;根本不要試圖稱呼它。如果沒有人關心這個事件x發生,你不能對此做任何事情。

你的代碼沒有責任關心是否有人在意它發生了什麼,而只是爲了通知他們,如果他們照顧的話就發生了。

EDIT 2 - 現在與代碼

public interface INeedToKnowAboutSomethingImportant 
{ 
    void WhenSomethingImportantHappens(SomethingImportantHappenedEventArgs args); 
} 


public class DoesSomethingImportant 
{ 
    private readonly INeedToKnowAboutSomethingImportant _needyDependency; 
    public DoesSomethingImportant(INeedToKnowAboutSomethingImportant needyDependency) 
    { 
     _needyDependency = needyDependency; 
    } 

    protected void SomethingImportantHappened(object sender, EventArgs e) 
    { 
     //Handle internally 
     _needyDependency.WhenSomethingImportantHappens(new SomethingImportantHappenedEventArgs(e)); 
    } 
} 

按照這個模式,你不必擔心是否有人訂閱了事件處理程序。你必須完成依賴關係,但所有並不重要,因爲無論它是什麼,它都會有你要調用的方法。

+0

感謝您的意見。我最初的想法是,NotImplementedException可能意味着該方法執行的邏輯尚未實現(例如發現),並且可能不指向調用該方法的類(它應該訂閱該事件) – Henno

+0

btw ..什麼是你的意思是有一個默認的用戶? – Henno

+0

我的意思是,如果你要在事件處理程序爲空時拋出異常,那麼你就是爲了所有意圖和目的而要求它被某物訂閱。如果是這種情況,您應該至少創建一個最初訂閱它的處理程序。如果處理程序列表以某種方式被清除,您仍然需要保留空處理,但是對於沒有其他人實際上在乎處理程序激發的情況,應該使用默認值。 – arootbeer

2

事件應該可選擇訂閱。 如果您的類必須調用方法,請改爲在其構造函數上傳遞委託。

+0

+1 - 好主意!您也可以將委託傳遞給相關的方法。 – TrueWill

+0

很簡潔的答案。強制代碼的用戶在編譯時在前端執行,而不是在運行時在後端執行。 – DanTheMan

0

您不應該擔心事件對象爲空。如果沒有人訂閱了該活動,那麼什麼都沒有。如果你需要另一個函數在你的事件提升類之外運行,那麼你需要使用除了觀察者模式之外的另一個模式。正如Eduardo建議你可以傳入一個委託,你也可以考慮一個構建器模式。

0

如果事件沒有訂閱者,我不會拋出。

在引發事件的「On」方法中,您將需要一個null test(注意競爭條件預防)。在其他地方,你的班級不應該認爲該活動有訂戶。

1

當你檢查你的事件時,你不應該拋出NotImplementedException。只需檢查,如果不爲空則執行。例如:

。你在頁面上放置一個元素,但你不打算在按鈕上實現任何事件。按鈕檢查Click事件,沒有找到它,並拋出NotImplementedException。

現在,這只是錯誤的。

事件是在程序被擊中某個點時引發的。然後你可以擁有由它「觸發」的代碼。代碼的主要路徑不應受到事件是否存在的影響。如果沒有觸發事件,代碼的主路徑無法繼續,那麼您需要改用Method。

我的建議是: 1)創建一個活動。 2)訂閱將要稍後實施的處理程序事件。 3)在處理程序中拋出NotImplementedException。

至於異常是未處理的,你永遠不應該處理NotImplementedException無論如何:P ...(你不應該拋出NotImplementedException對事件的空引用)。