Dot-Net

從您的方法返回異常是不好的做法

  • October 21, 2017

我的同行編寫的許多程式碼庫方法都執行自己的錯誤處理,通常是通過擷取、通知和記錄。

在這些情況下,方法返回一個布爾值,指示成功或失敗。

但有時,如果一個方法失敗,我希望呼叫程式碼知道原因,並且返回一個布爾值是不夠的。

解決這個問題的一種方法是在方法中保留錯誤處理,但使方法無效,並讓方法拋出它們的異常。

但是,最近我養成了在適當的方法中返回異常的習慣,通常是可能無效的操作方法,但我想知道操作的狀態。

返回 Exception 比讓 void 方法拋出 Exception 的優點是,我認為它使其他程序員更容易使用您的庫,更重要的是,這意味著您可以安全地呼叫該方法而不必擔心擷取例外

例如,如果方法只是 void,則程序員應該處理成功或失敗可能不會立即顯而易見。

但是,如果這些方法專門指定了返回類型 Exception,那麼您就知道可以根據需要檢查成功或失敗。但這也意味著如果您不想擷取錯誤,則無需擔心。

那有意義嗎?也許我沒有使用最好的例子,但一般來說,返回異常是否可以,或者那裡有更好的模式?

更新

哇,壓倒性的結果是沒有辦法的。我是這麼想的。我必須說,這樣做(返回異常)有點解決問題,但確實感覺不對。

因此,從您的一些答案來看,這些特定場景(複雜類,或具有一個或多個外部依賴項(即 Web 服務)的類)的最佳解決方案似乎是自定義結果類?

更新:

我真的很感激所有的意見,我正在閱讀所有內容,並且我正在仔細考慮所有的輸入。

目前我更喜歡有一個 void 方法,拋出異常,然後在外面擷取它們……那更好嗎?

如果你的意思是……

public Exception MyMethod( string foo )
{
  if( String.IsNullOrEmpty() )
  {
     return new ArgumentNullException( "foo" );
  }
}

… 而不是 …

public void MyMethod( string foo )
{
  if( String.IsNullOrEmpty() )
  {
     throw new ArgumentNullException( "foo" )
  }
}

那麼絕對不行,那樣做是不行的。您將完全重新發明異常的目的並將其用作結果。以下是一些標準的最佳實踐

另一個不這樣做的好理由是標準委託將不再匹配您的方法簽名。因此,例如,您不能再Action<string>在 MyMethod 上使用,而是需要使用Func<string,Exception>

@Andy,每條評論,回答太長了:不是真的。不要太在意來電者。無論如何,他的設計應該是防禦性的。想想異常的語義……“除非有人知道如何解決這個問題,否則這個應用程序的執行將在這裡停止。” 如果你能解決問題,你應該解決它。如果你不能,你必須記錄它並把它扔到一個新的水平,因為他們可能知道該怎麼做。

你應該處理你能處理的東西,扔掉你不能處理的東西。根據定義,呼叫堆棧上的人比你擁有更廣闊的世界觀。您的應用程序需要具有處理異常並繼續執行的能力。他們這樣做的唯一方法是防禦性編碼,並將問題提升到更高級別的資訊,看看是否可以做任何事情。

最終,如果答案是“否”,那麼將問題記錄到它可以理解,做一個好公民,優雅地終止應用程序,再活一天。不要自私,並嘗試為您的來電者隱藏錯誤。保持防守,他也會這樣做。:)

查看企業庫異常處理塊。它認為他們真正闡明瞭如何處理整個架構中的異常的偉大願景。

引用自:https://stackoverflow.com/questions/973292