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

C# 3.0匿名類型編譯器生成機制深度解析(三):IL反編譯驗證與類型復用策略

     編輯:關於C語言

匿名類型編譯器生成過程

源代碼:


var noname = new { NameA = "dd", Age = 24 };
var qname = new { NameA = "ff", Age = 25 };

編譯器生成的等價C#偽代碼:


class __Anonymous1
{
    private string _nameA;
    private int _age;
    public string NameA { get => _nameA; set => _nameA = value; }
    public int Age { get => _age; set => _age = value; }
}

__Anonymous1 noname = new __Anonymous1();
noname.NameA = "dd";
noname.Age = 24;

__Anonymous1 qname = new __Anonymous1(); // 復用同一類型
qname.NameA = "ff";
qname.Age = 25;

ILDasm反編譯驗證類型復用

使用ILDasm.exe查看編譯後程序集:

  1. 編譯包含上述代碼的項目。
  2. 打開生成的.exe/.dll。
  3. 查看類型列表,僅出現一個**<>f__AnonymousType0`2類型。
  4. 確認noname與qname均為該類型實例。

結論:編譯器識別結構相同(屬性名、順序、類型均同)的匿名類型,僅生成一個**類型定義,多處復用。

完整驗證代碼結構


public class EDClass
{
    public string Name { get; private set; }
    public EDClass() => Name = "QQ1";
    public void SetName() => Name = "QQ";
    
    public void TestAnonymous()
    {
        var noname = new { NameA = "dd", Age = 24 };
        var qname = new { NameA = "ff", Age = 25 };
        
        Console.WriteLine(qname == noname);           // False
        Console.WriteLine(qname.Equals(noname));      // True
        Console.WriteLine(qname.GetHashCode() == noname.GetHashCode()); // True
    }
}

編譯器類型復用規則

  • 同一程序集內。
  • 屬性名稱、順序、類型**完全一致。
  • 屬性名區分大小寫。
  • 不同程序集間不復用**(各自生成內部類型)。

實際開發啟示

  • LINQ多處投影相同結構時,編譯器自動優化,無額外類型膨脹。
  • 跨程序集傳遞匿名類型會導致類型不匹配,務必在程序集邊界轉換為具名類型。
  • 反射獲取匿名類型時,類型名不穩定(編譯器決定),不可硬編碼依賴。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved