.NET----錯誤和異常處理機制

前言

  錯誤的出現並不老是編寫程序的人的緣由,有時應用程序會由於應用程序的最終用戶引起的動做或運行代碼的環境發生錯誤。不管如何,咱們都應預測應用程序中出現的錯誤,並相應的進行編碼。html

  .Net改進了處理錯誤的方式。C#處理錯誤的機制能夠爲每種錯誤提供自定義處理方式,並把識別錯誤的代碼與處理錯誤的代碼分別開來。編程

異常類

  在C#中當出現某個特殊的異常錯誤條件時,就會建立拋出一個異常對象,這個對象包含有助於跟蹤問題的信息。.Net提供了許多預約義的異常類,咱們下面看看一些常見特別的異常類吧(異常類太多了,這裏就介紹幾個常見的)。c#

  對於.Net類,通常的異常類System.Exception派生自System.Object,一般不在代碼中拋出System.Exception泛型對象,由於他們沒法肯定錯誤狀況的本質。數組

  在該層次中有兩個重要的類,他們派生自System.Exception類:性能

    •  SystemException------該類用於一般由.NET容許庫拋出的異常,或者由幾乎全部的應用程序拋出的異常。例如,若是.NET運行庫檢測到棧已滿,他就會拋出StackOverflowException異常。另外一方面,若是檢測到調用方法時參數不對,就能夠在本身的代碼中選擇拋出ArgumentException異常或其子類。SystemException異常的子類包括表示致命錯誤和非致命錯誤的異常。
    •  ApplicationException----在.NET Framework最初的設計中,是打算把這個類做爲自定義應用程序異常類的基類的。不過,CLR拋出的一些異常類也派生自這個類。應用程序拋出的異常則派生自SystemException。所以從ApplicationException派生自自定義異常類型沒有任何好處,取而代之的是,能夠直接從Exception基類派生自定義異常類。

  其餘可能會用到的異常類包括:學習

    •  StackOverflowException-------若是分配給棧的內存區域已滿,就會拋出這個異常。若是一個方法連續地遞歸調用本身,就可能發生棧溢出。這通常是一個致命錯誤,由於它禁止應用程序執行除了中斷之外的其餘任務。在這種狀況下,甚至也不可能執行到finally塊。一般用戶本身不能處理像這樣的錯誤,而應退出應用程序。
    •  EndOfStreamException-------這個異常一般是由於讀到文件末尾而拋出的,流表示數據源之間的數據流。
    •  OverflowException-----若是要在checked上下文中把包含-40的int類型數據強制轉換爲uint數據,就會拋出這個異常
    •  MemberAccessException----------該類用於處理訪問類的成員失敗時所引起的異常。失敗的緣由可能的緣由是沒有足夠的訪問權限,也多是要訪問的成員根本不存在(類與類之間調用時經常使用)
    •  IndexOutOfException-------該類用於處理下標超出了數組長度所引起的異常

使用try...catch...finally捕獲異常

  • try 塊包含的代碼組成了程序的正常操做部分,但這部分程序可能會遇到某些嚴重的錯誤。
  • catch塊包含的代碼處理各類錯誤,這些錯誤是執行try塊中的代碼時遇到的問題。這個快能夠用來記錄錯誤。
  • finally快包含的代碼清理資源或執行一般要在try塊或者catch塊末尾執行的其餘操做。不管是否拋出異常,都會執行finally塊。finally塊中防止return語句,編譯器會標記一個錯誤。另外此塊能夠若是沒有須要關閉或者處理的其餘操做能夠省略此塊。

 

  異常處理具備性能含義,在常見的狀況下,不該該使用異常處理錯誤。應儘可能編寫好避免錯誤出現的代碼。ui

  在異常捕獲中,咱們能夠實現多個catch塊來針對不一樣的錯誤作出對應的錯誤處理。下面咱們看一個例子:編碼

class Program
    {
        static void Main(string[] args)
        {
            while (true)
            {
                try
                {
                    string userInput;
                    Console.WriteLine("請輸入0-5之間任意一個數字:");
                    userInput = Console.ReadLine();
                    if (string.IsNullOrWhiteSpace(userInput))
                    {
                        break;
                    }


                    if (int.TryParse(userInput, out int index))
                    {
                        if (index < 0 || index > 5)
                        {

                            throw new IndexOutOfRangeException($"你輸入的數字是{index}");

                        }
                        Console.WriteLine($"你輸入的數字是{index}");
                    }
                    else
                    {
                        throw new Exception("請輸入數字");
                    }
                }
                catch (IndexOutOfRangeException ex)
                {
                    Console.WriteLine($"你輸入的數字不在此範圍內.{ex.Message}");
                }
                catch (Exception ex)
                {

                    Console.WriteLine(ex.Message);
                }
                finally
                {
                    Console.WriteLine("謝謝合做");
                }

               
            }
        }
    }

 

  在此事例中,定義了兩個catch塊。若是輸入的超過規定返回的數字,則會拋出超出範圍的錯誤也就進入對應的catch塊。而輸入的非數字也就進入了另一個catch塊進行處理。spa

  下面咱們看一看關於System.Exception屬性。熟悉瞭解其中熟悉能更好的去觀察理解拋出的異常錯誤。設計


  

過濾異常、建立用戶定義的異常

  自從C#6開始就支持異常過濾器。Catch塊僅在過濾器但會true時執行。捕獲不一樣的異常類型時,能夠有行爲不一樣的代碼塊。在某些狀況下,catch塊基於異常的內容執行不一樣的操做。下面咱們看下如何來使用異常過濾器吧:

 public class MyIndexOutOfException :SystemException
    {
        public MyIndexOutOfException(string message) : base(message)
        {

        }

        public int ErrorCode { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                int steInput = 12;

                if (steInput > 10)
                {
                    throw new MyIndexOutOfException("數據超出了範圍") { ErrorCode = 1 };
                }

            }

            catch (MyIndexOutOfException ex) when (ex.ErrorCode!=1)

            {
                Console.WriteLine("出現了自定義錯誤");
            }

            catch (MyIndexOutOfException ex) when (ex.ErrorCode == 1)
            {
                Console.WriteLine(ex.Message);
            }

            catch (Exception ex)
            {

                throw;
            }
        }
    }

 

  上面例子中,自定義了一個異常處理,同時增長ErrorCode,以此來做爲過濾條件,利用關鍵字When+條件來進行過濾。

總結

  本篇文章介紹了異常處理錯誤的狀況及機制,咱們不只能夠輸出代碼好難過的通常錯誤代碼,也能夠輸出咱們本身定義的特殊錯誤狀況。不管編程技術有多好,程序都必須能處理可能出現的任何錯誤。對不一樣的錯誤採起相應的應對措施,纔是正確編碼的其中一步。

 

      不是井裏沒有水,而是你挖的不夠深。不是成功來得慢,而是你努力的不夠多。


 

 

               c#基礎知識詳解系列

 

歡迎你們掃描下方二維碼,和我一塊兒學習更多的C#知識

  

  

相關文章
相關標籤/搜索