《.NET 設計規範》第 7 章:異常

來源:互聯網
上載者:User

標籤:environ   exce   方式   engine   out   ati   test   try   執行   

第 7 章:異常

  異常與各種物件導向語言整合得非常好。

  異常增強了 API 的一致性。

  在用傳回值來報告錯誤時,錯誤處理的代碼與可能會發生錯誤的代碼距離總是很近。

  更容易使錯誤處理的帶碼全域化。

  錯誤碼很容易被忽略,而且經常會被忽略。

  異常可以包含豐富的資訊來對錯誤的原因加以描述。

  異常允許使用者定義未處理異常的處理常式。

  異常可以包含豐富的資訊來對錯誤額原因加以描述。

  異常允許使用者定義未處理異常的處理常式。

  異常有助於檢測。

 

7.1 拋出異常

  不要返回錯誤碼。

  要通過拋出異常的放回來報告操作失敗。

  考慮在代碼遇到嚴重問題且無法繼續安全地執行時,通過調用 System.Environment.FailFast 來終止進程,而不要拋出異常。

  不要在正常的控制流程中使用異常,如果能夠避免的話。

  考慮拋出異常可能會對效能造成的影響。對大多數的應用程式來說,每秒拋出 100 個異常很可能會嚴重地影響效能。  

  要為所有的異常撰寫文檔,並把它們作為契約的一部分 - 如果異常是因為在調用公有成員時違反了它的契約而拋出的(非系統失敗)。

  不要讓公有成員根據某個選項來決定是否拋出異常。

  不要把異常用作公有成員的傳回值或輸出參數。

  考慮使用輔助方法來建立異常。

  不要在異常過濾程式中拋出異常。

  避免顯式地從 finally 代碼塊中拋出異常。隱式地拋出異常,即在調用其它方法時由其它方法拋出異常,是可以接受的。

 

7.2 為拋出的異常選擇合適的類型

  不要為了通報使用錯誤而建立新的異常類型。在這種情況下應該拋出架構中已有的異常。

  考慮為程式錯誤建立並拋出自訂的異常 - 如果對它的處理方式和對其它異常的處理方式有所不同。否則,應該拋出已有的異常。

  不要建立新的異常類型 - 如果對該錯誤的處理和對架構中已有異常的並沒有什麼不同。在這種情況下應該拋出架構中已有的異常。

  要建立新的異常類型來傳達獨一無二的程式錯誤 - 如果不能通過架構中已有的異常來傳達該錯誤。

  避免設計出會導致系統失敗的 API。如果此類失敗可能會發生,那麼在發生系統失敗時應該調用 Environment.FailFast,而不應該拋出異常。

  不要僅僅為了擁有自己的異常而建立並使用新的異常。

  要使用合理的、最具針對性(最底層衍生類別)的異常。

  要在拋出異常時為開發人員提供豐富而有意義的錯誤訊息。

  要確保異常訊息的文法正確無誤。

  要確保異常訊息中的每個句子都有句號。

  避免在異常訊息這種使用問號和驚歎號。

  不要在沒有得到許可的情況下在異常訊息中泄漏安全訊息。

  考慮把組件拋出的異常訊息本地化 - 如果想讓沐浴為其它語言的開發人員也能使用組件。

  不要在架構的代碼捕獲具體類型不確定的異常(比如 System.Exception、System.SystemException,等等)時,把錯誤吞了。

  避免在應用程式的代碼中,在捕獲具體類型不確定的異常(比如 System.Exception、System.SystemException,等等)時,把錯誤吞了。

  不要把任何特殊的異常排除在外 - 如果編寫 catch 代碼塊的目的就是為了轉移異常。

  考慮捕獲特定類型的異常 - 如果確實理解該異常在具體環境中產生的原因,並能對錯誤做出適當的反應。

  不要捕獲不應該捕獲的異常。通常應該允許異常沿著調用棧向上遊傳遞。

  要在進行清理工作時使用 try-finally,避免使用 try-catch。對精心編寫的異常代碼來說,try-finally 的使用頻率要比 try-catch 高得多。

  要在捕獲並重新拋出異常時使用空的 throw 語句。這是保持異常調用棧不變的最好方法。

  不要用無參數的 catch 塊來處理不符合 CLS 規範 規範的異常(不是派生自 System.Exception 的異常)。

  考慮對較低層次拋出的異常進行適當地封裝 - 如果較低層次的異常在較高層次的運行環境中沒有什麼意義。

  避免捕獲並封裝具體類型不確定的異常。

  要在對異常進行封裝時為其指定內部異常。

 

7.3 標準異常類型的使用

  不要拋出 System.Exception 或 System.SystemExceptio 異常。

  不要在架構代碼中捕獲 System.Exception 或 System.SystemException 異常,除非打算重新拋出。

  避免捕獲 System.Exception 或 Systen.SystemException 異常,除非是在頂層的異常處理器中。

  不要拋出 System.ApplicationException 或從它派生新類。

  要拋出 InvalidaOperationException 異常 - 如果對象處於不正確的狀態。

  要在使用者傳入無效參數時拋出 ArgumentException 異常或其子類型。如果可以的話,要盡量使用位於繼承層次末尾的異常類型。

  要在拋出 ArgumentException 異常或其子類時設定 ParamName 屬性。

  要在屬性的 setter 中,以 value 作為 value 隱式參數的名字。

  不要讓公用 API 顯式地或隱式地拋出 NullReferenceException、AccessViolationException 或 IndexOutOfRangeException 異常。這些異常時專門留給執行引擎來拋出的,大多數情況下它們表示代碼存在缺陷。

  不要顯式地拋出 StackOverflowException 異常。應該只有 CLR 才能顯式地拋出該異常。

  不要捕獲 StackOverflowException 異常。

  不要顯式地拋出 OutOfMemoryException 異常。應該只有 CLR 才能拋出異常。

  不要顯示地拋出 ComException、ExecutingEngineException 及 SEHException 異常,應該只有 CLR 才能拋出這些異常。

 

7.4 自訂異常的設計

  要從 System.Exception 或其它常用的異常基類派生新的異常。

  避免太深的繼承層次。

  要在命名異常類時使用“Exception”尾碼。

  要使異常可序列化。為了使異常能夠在跨應用程式定義域和跨遠程邊界時仍能正常使用,這樣做是必須的。

  要為所有的異常(至少)提供下面這些常用的建構函式。

  要通過 ToString 的一個覆蓋方法來報告與安全性有關的訊息,前提是必須先獲得相應的許可。

  要把與安全性有關的資訊儲存在私人的異常狀態中,並確保只有可信賴的代碼才能得到該資訊。

  考慮為異常定義屬性,這樣就能從程式中取得除了訊息字串之外與異常有關的額外資訊。

  

7.5 異常與效能

  不要因異常可能對效能造成負面影響而使用錯誤碼。

  考慮在成員中使用 Tester-Doer 模式來避免因異常而引起的效能問題 - 如果成員在常用情境中都可能拋出異常。

  考慮在成員中使用 Try-Parse 模式來避免因異常而引起的效能問題,如果成員在常用代碼中都可能會拋出異常。

  要在實現 Try-Parse 模式時使用“Try”首碼,並用布爾類型作為方法的傳回型別。

  要為每個使用 Try-Parse 模式的方法提供一個會拋出異常的對應成員。

  

《.NET 設計規範》第 7 章:異常

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.