首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# try/catch/finally 實戰範例:異常捕捉與資源清理完全指南

     編輯:關於C語言

前言

try/catch/finally 是 C# 結構化異常處理的基石。熟練掌握這三個區塊的協作方式,能讓程式在發生錯誤時既能妥善處理,又能確保資源正確釋放。本文透過實際程式碼範例,示範如何將底層異常轉換為更具語意的高層異常,以及 finally 在資源管理上的關鍵角色。

一、使用 try/catch 處理異常

try-catch 的核心目的是攔截工作程式碼產生的異常。部分異常可在 catch 中完全處理並恢復執行;更多情況下,我們需要將其轉換為更適合呼叫端理解的異常類型。

範例:將 IndexOutOfRangeException 轉為 ArgumentOutOfRangeException

當方法接收索引參數存取陣列時,若發生越界,原始的 IndexOutOfRangeException 屬於實作細節,對呼叫者而言,ArgumentOutOfRangeException 更能精確表達「參數值不合法」的語意。

class TestTryCatch
{
    static int GetInt(int[] array, int index)
    {
        try
        {
            return array[index];
        }
        catch (IndexOutOfRangeException e)
        {
            Console.WriteLine(e.Message);
            // 將原始異常包裝為 InnerException,保留完整錯誤鏈
            throw new ArgumentOutOfRangeException(
                "index 參數超出範圍", e);
        }
    }
}

關鍵說明

  • 導致異常的程式碼置於 try 區塊。
  • catch 指定要處理的具體異常類型(IndexOutOfRangeException)。
  • 建立新異常時,透過建構函式將原始異常指定為 InnerException,提供呼叫端完整診斷脈絡。
  • InnerException 為唯讀屬性,必須在建構時指定。

二、使用 finally 執行清理程式碼

finally 的存在意義在於「保證執行」。即使 try 區塊中發生異常、catch 處理中途再次擲回、或使用 return 離開方法,finally 區塊仍會執行。這使其成為釋放非受控資源(檔案控制代碼、資料庫連線、網路通訊端等)的最佳位置。

未使用 finally 的風險

static void CodeWithoutCleanup()
{
    FileStream file = null;
    FileInfo fileInfo = new FileInfo(@"C:\file.txt");
    file = fileInfo.OpenWrite();
    file.WriteByte(0xF);
    file.Close();  // 若 WriteByte 擲回異常,Close 永不會被呼叫
}

若 WriteByte 擲回異常,file.Close() 不會執行,檔案控制代碼洩漏,直到記憶體回收器介入(時機不可預期)。

正確模式:try-catch-finally

static void CodeWithCleanup()
{
    FileStream file = null;
    FileInfo fileInfo = null;

    try
    {
        fileInfo = new FileInfo(@"C:\file.txt");
        file = fileInfo.OpenWrite();
        file.WriteByte(0xF);
    }
    catch (UnauthorizedAccessException e)
    {
        Console.WriteLine(e.Message);
    }
    finally
    {
        // OpenWrite 可能失敗,file 可能為 null,必須檢查
        if (file != null)
        {
            file.Close();
        }
    }
}

關鍵細節

  1. Null 檢查:OpenWrite() 可能在建立 FileStream 前失敗,導致 file 保持 null。直接呼叫 file.Close() 會擲回 NullReferenceException,汙染原始錯誤資訊。
  2. 避免 finally 中擲回異常:finally 區塊應盡量純粹執行清理,若清理邏輯本身可能失敗,需內部自行處理。
  3. 資料庫連線:同樣適用於 SqlConnection.Close(),確保連線儘快歸還連線池,避免耗盡可用連線數。

三、進階模式:using 陳述式

對於實作 IDisposable 的物件,C# 提供 using 語法糖,編譯器會自動展開為 try/finally 模式,程式碼更簡潔:

static void CodeWithUsing()
{
    using (FileStream file = new FileInfo(@"C:\file.txt").OpenWrite())
    {
        file.WriteByte(0xF);
    } // 編譯器保證這裡呼叫 file.Dispose()(相當於 Close())
}

這是現代 C# 開發中推薦的資源管理方式。

總結

  • try 定義受保護區域。
  • catch 處理特定異常,必要時包裝重新擲回並保留 InnerException。
  • finally 確保資源釋放,務必檢查 null。
  • 優先使用 using 簡化 IDisposable 物件的清理。

掌握這些模式,能讓您的 C# 程式在面對錯誤與資源管理時,展現專業級的穩健度。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved