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

C# using 與 as 運算子實務指南:資源管理與安全型別轉換

     編輯:關於C語言

前言

using 與 as 是 C# 兩大實用語法糖,分別解決資源確定性釋放與安全型別轉換問題。本文詳細說明用法、IL 機制、最佳實踐與常見誤區。

using 陳述式:確定性資源釋放

基本語法


// 完整形式
using (ResourceType resource = new ResourceType())
{
    resource.DoWork();
}  // 隱含 try/finally,保證呼叫 Dispose()

// C# 8.0+ using 宣告 (範圍至區塊結束)
using var resource = new ResourceType();
resource.DoWork();
// 區塊結束自動 Dispose

編譯器產生的 IL 邏輯


// 原始碼
using (var r = new Resource()) { r.Work(); }

// 等價展開
Resource r = new Resource();
try 
{
    r.Work();
}
finally
{
    if (r != null) 
        ((IDisposable)r).Dispose();
}

實作 IDisposable 模式


public class TestUsing : IDisposable
{
    private bool _disposed = false;
    
    public void DoWork() => Console.WriteLine("Do a method");
    
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    
    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                // 釋放託管資源
                Console.WriteLine("Dispose managed");
            }
            // 釋放非託管資源
            Console.WriteLine("Dispose unmanaged");
            _disposed = true;
        }
    }
    
    ~TestUsing() => Dispose(false);  // 終結器備援
}

適用場景

  • 檔案流 (FileStream, StreamReader/Writer)
  • 資料庫連線 (SqlConnection)
  • 圖形資源 (Graphics, Bitmap)
  • 網路連線 (HttpClient, TcpClient)
  • 任何實作 IDisposable 的物件

as 運算子:安全參考轉換

語法與等價邏輯


// as 運算子
string s = obj as string;

// 等價於
string s = (obj is string) ? (string)obj : null;

// 差異:as 只評估 obj 一次,is+cast 評估兩次

關鍵限制:僅限參考型別


// ✅ 參考型別:類別、介面、陣列、委派、string
object obj = "hello";
string s = obj as string;  // 合法

// ❌ 值型別:int、struct、enum、DateTime
object val = 123;
// int i = val as int;  // 編譯錯誤 CS0039

// ✅ 可為 null 的值型別
int? nullable = 123;
int? result = nullable as int?;  // 合法 (int? 是參考型別包裝)

實務範例:異質集合安全過濾


object[] items = { 123, "hello", 45.6, "world", DateTime.Now };

// 傳統寫法:try-catch 或 is+cast
foreach (object item in items)
{
    if (item is string s)  // C# 7+ 模式比對
        Console.WriteLine($"String: {s}");
}

// as 寫法 (C# 6 或偏好風格)
foreach (object item in items)
{
    string s = item as string;
    if (s != null)
        Console.WriteLine($"String: {s}");
}

using vs as 核心差異

特性usingas
目的資源生命週期管理安全型別轉換
適用對象IDisposable 實作類別參考型別轉換
失敗行為編譯期錯誤 (未實作 IDisposable)回傳 null (不拋出例外)
語法糖本質try/finally + Dispose()is 檢查 + 條件轉換
C# 8 新語法using 宣告—

常見誤區與避坑

誤區正確認知
using 適用於所有物件僅限實作 IDisposable 的型別
as 可用於 int、double 等值型別僅限參考型別;值型別用 nullable 或模式比對
as 轉換失敗拋出例外回傳 null,不拋出例外
using 區塊內拋出例外不會 Disposefinally 保證執行 Dispose,即使有例外
as 比 is+cast 慢as 只評估一次,理論略快或持平

進階:using 與非同步


// IAsyncDisposable (C# 8+)
await using var stream = new FileStream("test.txt", FileMode.Create);
await stream.WriteAsync(buffer);

// 非同步資源需 await using,否則 Dispose 可能在資料寫入完成前執行

總結

using 確保資源確定性釋放,是 IDisposable 模式的語法支柱;as 提供安全參考轉換,避免 InvalidCastException。兩者皆為 C# 語言層面的安全性保障,熟練掌握能寫出更健壯、可讀性更高的程式碼。

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