• <th id="ltxwt"></th>

      c# 異常處理 經典代碼實例

      2016-07-06
      一、C#的異常處理所用到關鍵字     try 用于檢查發生的異常,并幫助發送任何可能的異常。
           catch 以控制權更大的方式處理錯誤,可以有多個catch子句。
           finally 無論是否引發了異常,finally的代碼塊都將被執行。
           throw 用于引發異常,可引發預定義異常和自定義異常。
      ­
      二、C#異常處理的格式
      ­
      try
      {
         程序代碼塊;
      }
      catch(Exception e)
      {
         異常處理代碼塊;
      }
      finally
      {
         無論是否發生異常,均要執行的代碼塊;
      }
        
           三、異常處理實戰
           一個除數和零的簡單例子:
      public class DivisorIsZero
      {
      private static void Main()
      {
      int dividend=10;
      int divisor1=0;
      int divisor2=5;
      int DivideValue;
      try
      {
      DivideValue=dividend/divisor1;   //(1)
      //DivideValue=dividend/divisor2; //(2)
      System.Console.WriteLine("DivideValue={0}",DivideValue);//(3)這一行將不會被執行。
      }
      catch
      {
      System.Console.WriteLine("傳遞過來的異常值為:{0}",e);
      }
      finally
      {
      System.Console.WriteLine("無論是否發生異常,我都會顯示。");
      }
      }
      }
      ­
           注:(1)行被執行則會拋出一個異常,如果沒有catch語句,程序會異常終止,使用不帶參數的catch子句,則可以捕獲任意類型的異常。
         如果將(1)行注釋掉,啟用(2)行,這意味該程序運行時不會出現異常,從輸出可知,finally代碼塊仍將被執行。
      ­
         可以給try語句提供多個catch語句,以捕獲特定的異常,如上例中:0作為除數則會引發DivideByZeroException類型的異常,上例中的catch語句可以作如下修改:
      catch(DivideByZeroException e)
      {
           System.Console.WriteLine("零不能作為除數!異常值為:n{0}",e);
      }
      catch(Exception e)
      {
           System.Console.WriteLine("并非'零作為除數引發的異常"!異常值為:n{0}",e);
      }
           為什么還要加上一個catch(Exception e)子句呢?原因很簡單,catch(DivideByZeroException e)子句只能捕獲特定的異常,try內的程序代碼可能還會產生其它的異常,這些異常只能由catch(Exception e)來捕獲了。
      下表給出了一些常見的異常:
      ­
                   System名稱空間中常用的異常類
      ­
         異常類名稱                                  簡單描述
      MemberAccessException                                   訪問錯誤:類型成員不能被訪問
      ArgumentException                                           參數錯誤:方法的參數無效
      ArgumentNullException                                   參數為空:給方法傳遞一個不可接受的空參數
      ArithmeticException                                         數學計算錯誤:由于數學運算導致的異常,覆蓋面廣。
      ArrayTypeMismatchException                       數組類型不匹配
      DivideByZeroException                                   被零除
      FormatException                                               參數的格式不正確
      IndexOutOfRangeException                             索引超出范圍,小于0或比最后一個元素的索引還大
      InvalidCastException                                         非法強制轉換,在顯式轉換失敗時引發
      MulticastNotSupportedException                   不支持的組播:組合兩個非空委派失敗時引發
      NotSupportedException                                   調用的方法在類中沒有實現
      NullReferenceException                                   引用空引用對象時引發
      OutOfMemoryException                                 無法為新語句分配內存時引發,內存不足
      OverflowException                                           溢出
      StackOverflowException                                 棧溢出
      TypeInitializationException                             錯誤的初始化類型:靜態構造函數有問題時引發
      NotFiniteNumberException                             無限大的值:數字不合法
      ­
           四、定義自己的異常類
           除了預定義的異常外,我們還可以創建自己的異常,過程比較簡單:
           ㈠聲明一個異常,格式如下:
         class ExceptionName:Exception{}
           ㈡引發自己的異常:
         throw(ExceptionName);
      ­

      下面這個例子是精華部分,表明了異常處理執行的順序(圓圈中的數字即是執行的序號):

      using System;
      using System.Collections.Generic;
      using System.Text;
      using System.IO;

      namespace ExceptionTest
      {
          class Program
          {
              static void Main(string[] args)
              {
                  Program test = new Program();

                  ///①調用GenerateException
                  try
                  {
                      test.GenerateException();
                  }
                  ///⑦Main函數中的異常鏈不空,捕獲異常
                  catch (Exception ex)
                  {
                      int i = 1;
                      Console.WriteLine("/nMain函數現在所有的異常:");
                      while (ex != null)
                      {
                         
                          Console.WriteLine("/t異常{0}:{1}",i++,ex.Message);
                          ///依次輸出異常鏈上的異常
                          ex = ex.InnerException;
                      }
                  }
                  ///⑧執行finally
                  finally
                  {
                      Console.WriteLine("main函數結束!");
                  }
                  Console.ReadKey();
              }
              void GenerateException()
              {
                  ///②執行GenerateException
                  Console.WriteLine("調用GenerateException");
                  int mySize = 3;
                  byte[] Mystream = new byte[mySize];
                  int iterations = 5;
                  ///③數組發生越界
                  try
                  {
                      for (byte b = 0; b < iterations; b++)
                      {
                          Mystream[b] = b;
                      }
                  }
                  ///④定義了多個catch塊,只執行最合適的
                  catch (IndexOutOfRangeException iore)
                  {
                      Console.WriteLine("catch越界異常:{0}", iore.Message);
                      ///⑤拋出一個異常,第二個參數為此異常的InnerException
                      throw new Exception("我拋出的異常", iore);
                  }
                 
                  catch (Exception ex)
                  {
                      Console.WriteLine("GenerateException中捕獲普通異常:{0}", ex.Message);
                  }
                  ///⑥執行finally
                  finally
                  {
                      Console.WriteLine("GenerateException結束");
                  }

              }
          }
      }

       


      天堂网