C#異常

来源:http://www.cnblogs.com/ctddjyds/archive/2017/07/31/7265153.html
-Advertisement-
Play Games

異常簡介 C sharp中的異常用於處理系統級和應用程式級的錯誤狀態,它是一種結構化、統一的類型安全的處理機制。異常處理相對於返回錯誤代碼的一個最大優點在於,異常可以被自動傳遞,這樣,在編程時異常更加難以被忽視。 C#的異常機制非常類似於C++的異常處理機制,但是還是有一些重要的區別: 1,在C#中 ...


異常簡介

C sharp中的異常用於處理系統級和應用程式級的錯誤狀態,它是一種結構化、統一的類型安全的處理機制。異常處理相對於返回錯誤代碼的一個最大優點在於,異常可以被自動傳遞,這樣,在編程時異常更加難以被忽視。

C#的異常機制非常類似於C++的異常處理機制,但是還是有一些重要的區別:

1,在C#中,所有的異常必須由從System.Exception派生的類來表示。在 C++ 中,可以使用任何類型的任何值表示異常。

2,在C#中,利用finally 塊可編寫在正常執行和異常情況下都將執行的終止代碼。在C++中,很難在不重覆代碼的情況下編寫這樣的代碼。

3,C# 中,系統級的異常如溢出、被零除和 null 等都對應地定義了與其匹配的異常類,並且與應用程式級的錯誤狀態處於同等地位。

引發異常的原因

1.throw 語句用於立即無條件地引發異常。控制永遠不會到達緊跟在 throw 後面的語句。

2.在執行C#語句和表達式的過程中,有時會出現一些例外情況,使某些操作無法正常完成,此時就會引發一個異常。例如,在整數除法運算中,若分母為零引發 System.DivideByZeroException。

System.Exception 

System.Exception類是所有異常的基類型。若幹個異常類直接從Exception繼承。 

ApplicationExceptionSystemException繼承該類,幾乎是所有運行時異常的基礎。

此類具有一些所有異常共用的值得註意的屬性:

· Message 是string類型的一個只讀屬性,它包含關於所發生異常的原因的描述(易於人工閱讀)。

· InnerException 是 Exception 類型的一個只讀屬性。

如果它的值不是 null,則它所引用的是指導致了當前異常的那個異常,即表示當前異常是在處理那個InnerException的catch 塊中被引發的。

如果它的值為 null,則表示該異常不是由另一個異常引發的。

以這種方式鏈接在一起的異常對象的數目可以是任意的。此屬性可用來在異常處理過程中創建和保留一系列異常。可使用此屬性創建一個新異常來包含以前捕捉的異常。原始異常可

由 InnerException 屬性中的第二個異常捕獲,這使處理第二個異常的代碼可以檢查附加信息。

例如,假設有一個讀取文件並格式化相應數據的方法。 代碼嘗試從文件讀取,但引發FileException。該方法捕捉 FileException 並引發 BadFormatException。在此情況下,FileException 可保存在 BadFormatException 的 InnerException 屬性中。

為提高調用方確定異常引發原因的能力,有時可能需要方法捕捉幫助器常式引發的異常,然後引發一個進一步指示已發生的錯誤的異常。 可以創建一個更有意義的新異常,其中內部異常引用可以設置為原始異常。 然後可以針對調用方引發這種更有意義的異常。 請註意,使用此功能,可以創建以最先引發的異常作為結束點的一系列相鏈接的異常。

·StackTrace 屬性

此屬性包含可用來確定錯誤發生位置的堆棧跟蹤。如果有可用的調試信息,則堆棧跟蹤包含源文件名和程式行號。

·Data 屬性:此屬性是可以保存任意數據(以鍵值對的形式)的IDictionary。

異常的處理方式

先執行try裡面的語句,如果try裡面的語句拋出了錯誤,就會被catch捕獲,所以就會中斷try裡面語句的執行轉而執行catch裡面的語句,如果try裡面的語句都執行完了也沒有拋出錯誤,那麼catch里的語句就沒有機會執行了。最後不論try順利運行完畢,還是try拋出了錯誤被catch語句捕獲並執行了catch的語句都要接著執行finally裡面的語句。

發生異常時,系統將搜索可以處理該異常的最近的 catch 子句(根據該異常的運行時類型來確定)。首先,搜索當前的方法以查找一個詞法上包含著它的 try 語句,並按順序考察與該 try 語句相關聯的各個 catch 子句。如果上述操作失敗,則在調用了當前方法的方法中,搜索在詞法上包含著當前方法調用代碼位置的 try 語句。此搜索將一直進行下去,直到找到可以處理當前異常的 catch 子句(該子句指定一個異常類,它與當前引發該異常的運行時類型屬於同一個類或是該運行時類型所屬類的一個基類)。註意,沒有指定異常類的 catch 子句可以處理任何異常。找到匹配的 catch 子句後,系統將把控制轉移到該 catch 子句的第一條語句。在 catch 子句的執行開始前,系統將首先按順序執行嵌套在捕捉到該異常的 try 語句裡面的所有 try 語句所對應的全部 finally 子句。

如果沒有找到匹配的 catch 子句,則發生下列兩種情況之一:

· 如果對匹配的 catch 子句的搜索到達一個靜態構造函數或靜態欄位初始值設定項,則在導致調用該靜態構造函數的代碼位置引發 System.TypeInitializationException。該 System.TypeInitializationException 的內部異常將包含最初引發的異常。

· 如果對匹配的 catch 子句的搜索到達最初啟動當前線程的代碼處,則該線程的執行就會終止。此類終止會產生什麼影響,應由實現來定義。

特別值得註意的是在析構函數執行過程中發生的異常。如果在析構函數執行過程中發生異常且該異常未被捕獲,則將終止該析構函數的執行,並調用它的基類的析構函數(如果有)。如果沒有基類(如 object 類型中的情況),或者如果沒有基類析構函數,則該異常將被忽略。

 

異常類的層次結構
System.ArrayTypeMismatchException:當存儲一個數組時,如果由於被存儲的元素的實際類型與數組的實際類型不相容而導致存儲失敗,就會引發此異常。

System.DivideByZeroException:在試圖用零除整數值時引發。

System.IndexOutOfRangeException:在試圖使用小於零或超出數組界限的下標索引數組時引發。

System.InvalidCastException:當從基類型或介面到派生類型的顯式轉換在運行時失敗時引發。

System.NullReferenceException:在需要使用引用對象的場合,如果使用 null 引用時引發。

System.OutOfMemoryException:在分配記憶體(通過 new)的嘗試失敗時引發。

System.OverflowException:在 checked 上下文中的算術運算溢出時引發。

System.StackOverflowException:當執行堆棧由於保存了太多掛起的方法調用而耗盡時,就會引發此異常;這通常表明存在非常深或無限的遞歸。

System.TypeInitializationException:在靜態構造函數引發異常並且沒有可以捕捉到它的 catch 子句時引發。

 

產生TypeInitializationException的情況就包含以下幾種:

  1. 訪問類的某一靜態成員,而其他靜態成員的初始化(或靜態構造函數中)產生異常。

例如訪問ClassHelper.StaticString,由於靜態成員Field的初始化產生異常,因此調用ClassHelper.StaticString會拋出TypeInitializationException。

  1. 訪問類的某一靜態成員,該靜態成員的初始化(或靜態構造函數中)產生異常。

例如訪問ClassHelper.Field。

  1. 對該類進行初始化,而類中的某個靜態成員初始化(或靜態構造函數中)產生異常。

例如ClassHelper helper = new ClassHelper()。  

 

異常處理準則

  1. 通常只在最上層(一般是UI層)捕捉異常。如果要在其它層捕捉異常,除非是下列情況之一:
     (1)能夠處理該異常
     (2)能夠忽略該異常
     (3)需要轉換該異常為其它特定異常後拋出新異常
  2. UI層捕獲異常後,可以
     (1)將無關緊要的異常忽略。
     (2)將異常轉換為錯誤信息展現給用戶。
     (3)如果是重大異常,可以考慮終止應用程式。
  3. 如果產生Exception,給用戶提供一個友好的信息,但記錄與有關錯誤的所有可能的細節,包括它的發生時間,方法和類的名字等實際的錯誤信息。有助於診斷問題。

4.  可以在非最上層拋出自定義異常。如果是自定義異常,請保證其是可序列化的,並且保證其實現了Exception的三個構造函數。自定義異常不要繼承Exception基類。相反,繼承ApplicationException

5.異常的拋出與截獲需要很多的CPU時間,不要在所有的方法中寫的try - catch。只在有可能有某個特定的異常發生的方法中使用它。

6.始終捕獲特定的異常,而不是一般的異常和系統異常。

7.當發生異常時,為了確保清理占據的資源,使用try / finally塊。在finally子句中關閉的資源。使用try / finally塊,即使發生異常,也能確保資源disposed。

8.在一個catch塊中的代碼都應該至少部分地處理了所捕捉的異常。否則,就不要使用catch塊。

9.從構造函數中拋出異常。因為構造函數沒有返回值,所以沒有簡單的方法來想構造函數的調用者發出構造失敗的信號,這時便可以通過拋出異常來做到。比如構造參數與指定條件不符時,就拋出一個異常。

10.在以上前提的保證下,可以在非最上層使用AOP截獲(intercept)異常而進行日誌記錄,這樣通過日誌記錄,我們可以瞭解系統的運行狀態。也可以有一個應用程式級(線程級)的錯誤處理程式,您可以用它處理所有一般異常。在一個'意外一般錯誤'中,這個錯誤處理程式應該捕獲該異常並記錄他,除此之外,在應用程式關閉之前應該做出友好的信息提示或者允許用戶選擇忽略異常繼續。

記不起在哪裡看到過這樣一句話:在軟體實現中,異常和日誌都是重要的質量保證手段,異常和日誌總是同時出現的。可以說,異常是日誌記錄的重要/主要組成部分。

調試

使用斷點進入調試模式。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 以前成功將Office Web Server 2013部署在了本地伺服器上,此次是將Office Web Server 2013部署在阿裡雲伺服器Windows Server 2008和2012上,中途遇到一些坑,寫此文章,幫助後來人,同時做個記錄。 因為Office Web Server 2013 ...
  • 1. 作用 動態查看進程的變化,常用來查找最耗CPU資源的進程。 2. 用法 top 【參數】 參數: -d:後接秒數,就是整個進程界面更新的秒數。預設是5秒; -b:以批次的方式執行top,通常會搭配數據流重定向來將批處理的結果輸出成為文件; -n:後面接整數數字,與-b搭配使用,表示需要進行幾次 ...
  • Linux 操作系統的網卡設備的傳統命名方式是 eth0、eth1、eth2等,而 CentOS7 提供了不同的命名規則,預設是基於固件、拓撲、位置信息來分配。這樣做的優點是命名全自動的、可預知的,缺點是比 eth0、wlan0 更難讀,比如 ens33 。 一、命名規則策略 規則1: 對於板載設備 ...
  • VIm配置及使用筆記 ============================= 安裝 apt get install vim y 配置說明 vim /etc/vim/vimrc 在配置文件後加入這些配置項 使用說明 編輯模式 一般模式 + 跳轉行 + 移動游標 + 撤銷與恢復 + 複製與粘貼 命令 ...
  • 一.環境:發行版本:ubuntu 14.04 64bit 二.獲取要指定的用戶及組id 使用id命令 (筆者獲取的uid和gid都為1000) 三.獲取識別的硬碟路徑 sudo fdisk -l (筆者獲取的路徑是/dev/sdb1) 四.掛載 sudo mount /dev/sdb1 /media ...
  • 說明:本文示例使用的VS2017和MVC5。 系統無論大小、牛逼或屌絲,一般都離不開註冊、登錄。那麼接下來我們就來分析下用戶身份認證。 簡單實現登錄、註銷 以前在學習.net的時候不知道什麼Forms身份認證,直接用session實現登錄,效果也蠻好嘛。而且用戶信息存在服務端,安全。 前端代碼: 後 ...
  • 之前調用 WebService 都是直接添加服務引用,然後調用 WebService 方法的,最近發現還可以使用 Http 請求調用 WebService。這裡還想說一句,還是 web api 的調用簡單。 WebService 服務端代碼: 很簡單的代碼,只是用於演示。 客戶端調用代碼: 第一種讀 ...
  • IdentityServer4 是一個提供 認證服務,單點登錄/登出(SSO),API訪問控制,聯合認證通道的可定製、免費商業支持的框架。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...