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

C# 3.0 進階技巧:透過泛型方法強制轉型匿名類型

     編輯:關於C#

匿名類型的型別名稱僅存在編譯期,執行期無法在原始碼中直接參考。這導致跨方法傳遞時只能用 object 或 dynamic,失去強型別優勢。但利用編譯器對相同結構匿名類型產生單一型別的特性,我們可以透過泛型方法實現「強制轉型回強型別」。

核心原理

同一組件中,屬性名稱、型別、順序完全相同的匿名類型初始化器,編譯器會重用同一個產生型別。因此,若我們能在呼叫端建立一個「樣本實例」傳給泛型方法,方法內即可將 object 轉型為該具體匿名型別。

實作範例


public static T CastAnonymous<T>(object anonymous, T sample)
{
    return (T)anonymous;
}

public class User
{
    public string Name { get; set; }
}

public static void Main()
{
    var user = new User { Name = "Lucifer" };
    // 建立匿名類型實例
    var anon = new { Age = 26, UserName = user.Name, IsActive = false };
    
    // 傳遞為 object
    ProcessAnon(anon);
}

public static void ProcessAnon(object anonymous)
{
    // 在此建立「結構相同」的樣本,讓編譯器產生相同型別
    var sample = new { Age = 0, UserName = "", IsActive = false };
    
    // 強制轉型回強型別
    var typed = CastAnonymous(anonymous, sample);
    
    // 現在擁有完整 IntelliSense 與強型別存取
    Console.WriteLine($"{typed.Age} - {typed.UserName} - {typed.IsActive}");
}

關鍵點解析

  1. 樣本實例僅用於型別推斷:sample 參數值不被使用,僅提供給編譯器推斷 T 為目標匿名型別。
  2. 結構必須完全一致:屬性名、型別、順序任一不同,編譯器產生不同型別,轉型會拋出 InvalidCastException。
  3. 僅限同一組件:跨組件的匿名類型永不相同,此技巧失效。
  4. 反射替代方案:若結構不固定,應改用反射或 dynamic,雖失去編譯期檢查但更靈活。

適用場景與警示

此技巧屬於進階 Hack,適用於:

  • 內部框架代碼,需在管線中傳遞匿名類型並保持強型別存取
  • 單元測試輔助方法

生產代碼慎用: 結構變更極易導致執行期崩潰,且降低代碼可讀性。現代 C# 建議改用 record 型別(C# 9+)或具名 Tuple,獲得同等簡潔且型別安全的體驗。

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