共用方式為


例外處理 (C# 程式設計手冊)

更新:2007 年 11 月

C# 程式設計人員使用 try 區塊分割可能受到例外狀況影響的程式碼,而 catch 區塊則是用來處理任何產生的例外狀況。不論是否擲回例外狀況,都可以使用 finally 區塊執行程式碼。這有時是必要的處理方式,因為如果擲回例外狀況,便不會執行緊接在 try/catch 建構 (Construct) 後面的程式碼。Try 區塊必須要和 catch 或 finally 區塊一起使用,且可以包含多個 catch 區塊。例如:

try
{
    // Code to try here.
}
catch (SomeSpecificException ex)
{
    // Code to handle exception here.
    // Only catch exceptions you know how to handle.
    // Never catch base class System.Exception without
    // rethrowing it at the end of the catch block.
}
try
{
    // Code to try here.
}
finally
{
    // Code to execute after try here.
}
try
{
    // Code to try here.
}
catch (SomeSpecificException ex)
{
    // Code to handle exception here.
}
finally
{
    // Code to execute after try (and possibly catch) here.
}

try 陳述式若沒有 catch 或 finally 區塊,將導致編譯器錯誤。

Catch 區塊

catch 區塊可指定要攔截的例外狀況類型。此型別稱為「例外狀況篩選條件」(Exception Filter),且必須是衍生自 Exception 的型別。一般來說,除非您確切知道如何處理在 try 區塊中擲回的所有例外狀況,或除非在 catch 區塊結尾包含 throw 陳述式,否則請勿在 catch 區塊中指定 Exception

具有不同例外狀況篩選條件的多個 catch 區塊可以鏈結在一起。多個 catch 區塊是從由上至下進行評估的,但針對每個擲回的例外狀況,只會執行一個 catch 區塊。將會執行第一個 catch 區塊,此區塊會指定精確的型別或擲回例外狀況的基底類別。如果沒有 catch 區塊指定相符的例外狀況篩選條件,則會執行沒有篩選條件的 catch 區塊 (如果有的話)。重要的是要先將 catch 區塊和最特定的 (衍生的) 例外狀況類別放在一起。

當下列條件為 true 時,您應攔截例外狀況:

  • 您確實了解擲回例外狀況的原因,而且可執行特定復原動作,例如攔截 FileNotFoundException 物件並提示使用者輸入新檔名。

  • 您可以建立並擲回較特定的新例外狀況。例如:

    int GetInt(int[] array, int index)
    {
        try
        {
            return array[index];
        }
        catch(System.IndexOutOfRangeException e)
        {
            throw new System.ArgumentOutOfRangeException(
                "Parameter index is out of range.");
        }
    }
    
  • 若要部分處理例外狀況。例如,catch 區塊可以用來將項目加入至錯誤記錄,但之後會重新擲回例外狀況,以對例外狀況進行後續處理。例如:

    try
    {
        // try to access a resource
    }
    catch (System.UnauthorizedAccessException e)
    {
        LogError(e);  // call a custom error logging procedure
        throw e;      // re-throw the error
    }
    

Finally 區塊

finally 區塊可以清除在 try 區塊中執行的動作。如果有的話,在 try 和 catch 區塊執行之後會執行 finally 區塊。永遠都會執行 finally 區塊,不管是否擲回例外狀況,或是否找到與例外狀況型別相符的 catch 區塊。

finally 區塊可用來釋放資源 (例如檔案資料流、資料庫連接和圖形控制代碼),而不需等候執行階段中的記憶體回收行程完成物件。如需詳細資訊,請參閱using 陳述式 (C# 參考)

在此範例中,會使用 finally 區塊來關閉在 try 區塊中開啟的檔案。請注意,在關閉檔案控制代碼之前,會先檢查它的狀態。如果 try 區塊未開啟檔案,檔案控制代碼 (File Handle) 仍會設定為 null。或者,若成功開啟檔案且沒有擲回任何例外狀況,則依然會執行 finally 區塊,並關閉開啟的檔案。

System.IO.FileStream file = null;
System.IO.FileInfo fileinfo = new System.IO.FileInfo("C:\\file.txt");
try
{
    file = fileinfo.OpenWrite();
    file.WriteByte(0xF);
}
finally
{
    // check for null because OpenWrite
    // might have failed
    if (file != null)
    {
        file.Close();
    }
}

C# 語言規格

如需詳細資料,請參閱 C# 語言規格中的下列章節:

  • 16 例外狀況

  • 8.9.5 throw 陳述式

  • 8.10 try 陳述式

請參閱

概念

C# 程式設計手冊

參考

例外狀況和例外處理 (C# 程式設計手冊)

try-catch (C# 參考)

try-finally (C# 參考)

try-catch-finally (C# 參考)

其他資源

C# 參考