本文件已封存並已停止維護。

Exception 類別

表示應用程式執行期間所發生的錯誤。

命名空間: System
組件: mscorlib (在 mscorlib.dll 中)

[SerializableAttribute] 
[ComVisibleAttribute(true)] 
[ClassInterfaceAttribute(ClassInterfaceType.None)] 
public class Exception : ISerializable, _Exception
/** @attribute SerializableAttribute() */ 
/** @attribute ComVisibleAttribute(true) */ 
/** @attribute ClassInterfaceAttribute(ClassInterfaceType.None) */ 
public class Exception implements ISerializable, _Exception
SerializableAttribute 
ComVisibleAttribute(true) 
ClassInterfaceAttribute(ClassInterfaceType.None) 
public class Exception implements ISerializable, _Exception

這個類別是所有例外狀況的基底類別。發生錯誤時,系統或目前正在執行的應用程式會藉由擲回包含錯誤資訊的例外狀況來報告它。擲回之後,應用程式或預設的例外處理常式 (Exception Handler) 會處理例外狀況。

Common Language Runtime 提供例外處理模型,該模型是根據做為物件的例外狀況的表示,並分別將程式碼和例外處理程式碼分隔為 try 區塊和 catch 區塊。可有一或多個 catch 區塊,每個區塊指定來處理特定型別的例外狀況,或一個區塊指定來攔截比另一個區塊更特定的例外狀況。

如果應用程式處理執行應用程式碼的區塊期間所發生的例外狀況,則程式碼必須置於 try 陳述式 (Statement) 中。try 陳述式中的應用程式碼為 try 區塊。將處理 try 區塊所擲回的例外狀況的應用程式碼置於 catch 陳述式中,並稱為 catch 區塊。零或多個 catch 區塊與 try 區塊關聯,且每個 catch 區塊都包含可用來判斷它所處理的例外狀況型別的型別篩選條件。

try 區塊發生例外狀況時,系統會以相關聯的 catch 區塊在應用程式碼中的出現順序來搜尋它們,直到系統找到處理例外狀況的 catch 區塊為止。如果 Catch 區塊的型別篩選條件指定 TT 所衍生自的任何型別時,則 catch 區塊會處理型別 T 的例外狀況。當系統找到處理例外狀況的第一個 catch 區塊時,它會停止搜尋。因此,在應用程式碼中,必須先指定處理型別的 catch 區塊,再指定處理其基底型別 (Base Type) 的 catch 區塊,如這個章節後續的範例所展示的。處理 System.Exception 的 Catch 區塊會在最後指定。

如果與目前的 try 區塊相關的 catch 區塊都不處理例外狀況,且目前的 try 區塊套疊於目前呼叫中的其他 try 區塊中,則會搜尋與下一個封入的 try 區塊相關的 catch 區塊。如果找不到例外狀況的 catch 區塊,則系統會搜尋目前呼叫中的上一個巢狀層次。如果在目前呼叫中找不到例外狀況的 catch 區塊,則會傳遞例外狀況至呼叫堆疊的上方,且會搜尋堆疊框架 (Stack Frame) 以尋找處理例外狀況的 catch 區塊。呼叫堆疊的搜尋會繼續,直到已處理例外狀況,或呼叫堆疊上不存在任何框架為止。如果到達呼叫堆疊的頂端而未找到處理例外狀況的 catch 區塊,則預設的例外處理常式會處理它,且應用程式會終止。

例外狀況型別支援下列功能:

  • 人們可讀取的 (Human-Readable) 描述錯誤的文字。發生例外狀況時,Runtime 會使得文字訊息可以用來通知使用者錯誤的本質,並建議解決問題所採取的動作。這個文字訊息保留在例外狀況物件的 Message 屬性中。在建立例外狀況物件期間,您可以將文字字串傳遞至建構函式 (Constructor) 來描述該特定例外狀況的詳細資料。如果未提供建構函式錯誤訊息引數,則會使用預設的錯誤訊息。

  • 擲回例外狀況時的呼叫堆疊狀態。StackTrace 屬性會攜帶堆疊追蹤,該追蹤可用來判斷程式碼中錯誤發生的位置。堆疊追蹤會列出所有呼叫的方法,和發出呼叫之原始程式檔 (Source File) 中的行號。

兩種分類的例外狀況存在於基底類別 Exception 之下。

  • 衍生自 SystemException 的預先定義 Common Language Runtime 例外狀況類別。

  • 衍生自 ApplicationException 的使用者定義的應用程式例外狀況類別。

Exception 包括許多屬性,可協助您識別程式碼位置、型別、說明檔和例外狀況的原因:StackTraceInnerExceptionMessageHelpLinkHResultSourceTargetSiteData

當兩個或多個例外狀況之間存在相互關聯性 (Relationship) 時,InnerException 屬性會保留這個資訊。將擲回外部例外來回應這個內部例外。處理外部例外的程式碼可使用先前內部例外中的資訊,以更能適當處理錯誤。此例外狀況的補充資訊可以存放在 Data 屬性內。

在建立例外狀況物件期間,傳遞至建構函式的錯誤訊息字串必須予以當地語系化,而且可使用 ResourceManager 從資源檔取得。如需當地語系化資源的詳細資訊,請參閱 System.Resources 命名空間概觀和封裝和部署資源

若要提供使用者例外狀況發生原因的大量資訊,HelpLink 屬性可保留說明檔的 URL (或 URN)。

Exception 使用值為 0x80131500 的 HRESULT COR_E_EXCEPTION。

如需 Exception 執行個體的初始屬性值的清單,請參閱 Exception 建構函式。

效能考量

例外狀況的擲出與處理,都會耗費相當多的系統資源與執行時間,因此只有需要處理真正的異常情形時,才應該擲出例外狀況,而不是用來處理可以預料到的事件或流程控制。例如方法的引數無效時,應用程式擲出例外狀況就很合理,因為被呼叫的方法本來就預計應該會收到有效的參數,所以收到無效的引數,代表必定有不尋常的情形發生。相較之下,如果使用者的輸入無效,並不適合擲出例外狀況,因為使用者本來就有可能不小心輸入無效的資料。遇到這種狀況時,應該提供重新輸入的機制,讓使用者能夠重新輸入有效的資料才對。

只有遇到異常情況時才擲出例外狀況,然後只需要用一個適用於應用程式大部分情況的通用例外處理常式來攔截這些例外狀況就夠了,不需要針對各個例外狀況分別設計處理常式。這種做法的理由在於,大部分錯誤都可以由該錯誤發生位置附近的驗證與錯誤處理程式碼予以適當處理,根本不會擲出也不需要攔截任何例外狀況,因此這個通用例外處理常式,就真的只要攔截應用程式任何地方都可能擲出、真正出乎意料之外的例外狀況。

此外,如果傳回代碼已足夠,就不應擲回例外狀況,千萬不要把傳回代碼轉成例外狀況,也不要經常攔截例外狀況後就忽略它,然後又恢復正常處理。

下列程式碼範例展示定義來處理 ArithmeticException 錯誤的 catch 區塊。這個 catch 區塊也會攔截 DivideByZeroException 錯誤,因為 DivideByZeroException 衍生自 ArithmeticException,而且沒有為 DivideByZeroException 錯誤明確定義的 catch 區塊。

using System;

class ExceptionTestClass 
{
public static void Main() 
{
   int x = 0;
      try 
      {
         int y = 100/x;
      }
         catch (ArithmeticException e) 
         {
         Console.WriteLine("ArithmeticException Handler: {0}", e.ToString());
         }
            catch (Exception e) 
            {
            Console.WriteLine("Generic Exception Handler: {0}", e.ToString());
            }
      }	
}

import System.*;

class ExceptionTestClass
{
    public static void main(String[] args)
    {
        int x = 0;
        try {
            int y = 100 / x;
        }
        catch (ArithmeticException e) {
            Console.WriteLine("ArithmeticException Handler: {0}", e.ToString());
        }
        catch (System.Exception e) {
            Console.WriteLine("Generic Exception Handler: {0}", e.ToString());
        }
    } //main
} //ExceptionTestClass

C# 程式碼含有下列輸出:

ArithmeticException Handler: System.DivideByZeroException: Attempted to divide by zero. at ExceptionTestClass.Main()

Visual Basic 程式碼含有下列輸出:

ArithmeticException Handler: System.OverflowException: Exception of type System.OverflowException was thrown. at ExceptionTestClass.Main()

System.Object
  System.Exception
     衍生類別

這個型別的所有公用靜態成員 (即 Visual Basic 中的 Shared 成員) 都是安全執行緒。並非所有的執行個體成員均為安全執行緒。

Windows 98、 Windows 2000 SP4、 Windows CE、 Windows Millennium Edition、 Windows Mobile for Pocket PC、 Windows Mobile for Smartphone、 Windows Server 2003、 Windows XP Media Center Edition、 Windows XP Professional x64 Edition、 Windows XP SP2、 Windows XP Starter Edition

.NET Framework 並不支援各種平台的所有版本。如需支援平台版本的相關資訊,請參閱系統需求一節的內容。

.NET Framework

支援版本:2.0、1.1、1.0

.NET Compact Framework

支援版本:2.0、1.0
顯示: