2009-11-19 77 views
1

如果我有一個接口,這是我添加註釋,以確定具體的會拋出異常,它是確定用於實現類拋出不同異常?不同的實現類可以拋出不同的異常類型嗎?

A(壞)的例子是:

public interface IWidgetWorker { 
    /// <summary> 
    /// Do the work required for the specified work id. 
    /// </summary> 
    /// <param name="workId">The id of the piece of work to do</param> 
    /// <exception cref="ArgumentException">Thrown if workId is empty</exception> 
    public void DoWork(Guid workId); 
} 

public class DatabaseWidgetWorker : IWidgetWorker { 
    public void DoWork(Guid workId) { 
     // throw some database related exception 
    } 
} 

public class WebWidgetWorker : IWidgetWorker { 
    public void DoWork(Guid workId) { 
     // throw some web related exception 
    } 
} 

也許我添加WidgetWorkerException類?我在哪裏記錄實施類可能拋出的具體異常?

+0

.net框架做到這一點:'IDbCommand.ExecuteNonQuery'只定義InvalidOperationException,而'SqlCommand.ExecuteNonQuery'也可以拋出一個SqlException異常。 – Heinzi 2009-11-19 11:02:34

回答

3

部分往往預期文檔例外。這些例外在創建接口時是邏輯的,例如InvalidOperationException用於調用方法並且對象處於錯誤狀態,或者當傳遞不正確的參數時使用ArgumentOutOfRangeException

然而,接口可以在任意數量的方式來實現。一個實現完全有可能查看文件系統或調用數據庫,引入一系列異常,這些異常在界面定義時是不可預見的。

您想知道某個方法拋出特定異常的唯一原因是能夠處理該條件與一般異常處理的不同。當您通過接口進行呼叫時,您將針對接口進行編碼,而不是實施。您無法知道實現如何工作,因此無法以任何特定方式處理異常。你必須回到更一般的異常處理。

經驗法則應該是記錄在給定暴露接口的情況下合理的異常,但是您應該期望實現拋出超出這些異常的異常。強大的代碼將有一種以通用方式處理這些未知異常的機制。

0

實現類應該只拋出接口中指定的異常。如果接口沒有提供任何報告錯誤的可能性,那麼接口設計得不好或者實現者應該把它弄糟,因爲接口用戶確實是並不關心。

0

這可能是主觀的。我的感覺是,實施類應該拋出當時拋出的任何例外。該接口不聲明允許哪些異常,哪些不允許。編譯器不會查看您的註釋,並且類可以拋出其他異常並仍然是您的界面的有效實現。

如果由於某種原因,你需要這些例外是單一類型的,你可以抓住他們,並與原來的內部異常重新拋出他們無論IWidgetWorker.DoWork被調用。

的情況workId爲空,則呼叫轉到實施之前可以處理的,所以沒有理由不同的實現應該處理相同的檢查和ArgumentException的投擲。

在其他編程環境中可能會有所不同。我認爲可能的例外必須用某些語言來聲明,但不是在這裏。

你的接口可以說一些關於消費代碼將如何各種異常的解釋和什麼做的文檔。如果異常是這樣那樣的話,可能耗時代碼會在一段時間後再次嘗試,但在其他情況下會終止報告錯誤。接口設計

相關問題