簡體   English   中英

在 C# 中,是否有任何我不應該使用的內置異常?

[英]In C#, are there any built-in exceptions I shouldn't use?

.NET 框架中是否有任何我不應該在自己的代碼中拋出的異常,或者這是不好的做法? 我應該自己寫嗎?

您不應拋出由於用戶錯誤而由CLR自動拋出的任何異常。 例如

  • StackOverflowException
  • 的NullReferenceException
  • AccessViolationException
  • 等......

這樣做的原因是為調用API的人造成了混亂。 用戶應該能夠區分API主動拋出的異常和未主動拋出的異常(由CLR拋出)。

原因是主動拋出異常通常表示API中的已知狀態。 如果我調用一個API並拋出一個ArgumentException,我有理由期望給定的對象處於良好的狀態。 它認識到一種潛在的不良情況並積極地對其進行說明。 另一方面,如果它拋出NullRefrenceException,則表明API遇到未知錯誤,現在處於不可靠狀態。

另一個較小的原因是,當用戶代碼拋出而不是CLR時,這些異常的行為會有所不同。 例如,如果用戶代碼拋出,則可能捕獲StackOverflowException,但如果CLR拋出則不會。

編輯回應邁克爾的評論

您也不應該直接拋出Exception,ApplicationException或SystemException。 這些異常類型過於籠統,無法為調用API的代碼提供有意義的信息。 如果是,您可以在message參數中添加非常具描述性的消息。 但是根據消息捕獲異常並不是直接或可維護的。 根據類型捕獲它會好得多。

關於這個主題的FxCop規則: http//msdn.microsoft.com/en-us/library/ms182338( VS.80) .aspx

框架中的大多數異常類都不是為了重用,因為它們通常用於表示某些特定於框架的錯誤。 @JaredPar提到的那些一樣,框架使用它們來指示框架中的某些狀態。

在框架中有幾十個,也許幾百個例外,因此IMO列出我們應該使用的那些更有用。 在我的頭腦中,這些是我積極使用的:

對於用戶代碼中的其他錯誤條件,最佳做法是創建自己的異常類。

@Michael實際上有一種情況建議拋出NullReferenceException:如果擴展方法的第一個參數(“this”參數)為null。 您需要這樣做才能使空變量按預期運行。

微軟曾經告訴程序員不要直接從Exception繼承,而是使用ApplicationException作為他們的基類。 不確定這個意見是否仍然適用,但......

如果已經存在一個預定義的異常,它涵蓋了你的確切錯誤條件(比如“NullReferenceException”或“InvalidArgumentException”等) - 無論如何,拋出這些異常而不是在你自己的代碼中重新發明它們。

沒有人直接發布指向它的鏈接,所以這里是 MSDN 頁面,其中包含異常注意事項的完整列表

https://learn.microsoft.com/en-us/do.net/standard/design-guidelines/using-standard-exception-types

在投擲方面,注意事項是......

  • 系統異常
  • 應用異常
  • 空引用異常
  • 訪問沖突異常
  • 索引超出范圍異常
  • 堆棧溢出異常
  • 內存不足異常
  • 異常
  • 執行引擎異常
  • SEH異常

它還有一個不要捕獲的列表和關於你應該拋出哪些異常的建議

已經為您定義了幾個例外。 在推出自己的例外之前,請務必嘗試使用這些例外

在線例外設計指南中包含的原則意見(具體參見頁)。

“框架設計指南:可重用.NET庫的約定,慣用法和模式,第2版”一書中有更多細節和有關該主題的更多討論。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM