C# 3.0 引入的語法糖,允許無需預先定義類別,直接通過物件初始化器語法 new { Prop1 = val1, Prop2 = val2 } 創建唯讀、不可變的強類型物件。編譯器在編譯期自動生成對應的密封類別,包含屬性、Get/Set、建構函式、Equals/GetHashCode/ToString 重寫。
var p1 = new { Name = "A", Price = 3 };
Console.WriteLine($"Name = {p1.Name}, Price = {p1.Price}"); // 輸出 Name = A, Price = 3
等價於手寫:
class __Anonymous1
{
private string _name;
private int _price;
public string Name { get => _name; set => _name = value; }
public int Price { get => _price; set => _price = value; }
}
__Anonymous1 p1 = new __Anonymous1 { Name = "A", Price = 3 };
ILDASM 顯示編譯器生成類別名稱如 <Projection>f__0,包含:
_Name、_PriceName、Price (get/set)ExtensionAttribute(雖非擴展方法,但同屬編譯器生成標記)var p1 = new { Name = "A", Price = 3 };
var p2 = new { Name = "A", Price = 3 }; // 同一類型
// p1.GetType() == p2.GetType() → true
var p1 = new { Name = "A", Price = 3 };
var p2 = new { Name = "A" }; // 缺少 Price
// 生成 <Projection>f__0 和 <Projection>f__1 兩個類型
| 特性 | 說明 |
|---|---|
| 不可變 | 屬性唯讀(init-only),建構後不可修改(C# 9+ 可用 with 表達式產生副本) |
| 強類型 | 編譯期推斷屬性類型,IntelliSense 完整支援 |
| 值語義相等 | 自動重寫 Equals/GetHashCode:逐屬性比較值 |
| ToString 格式化 | 自動生成 { Name = A, Price = 3 } 格式 |
| 範圍限制 | 僅能作為區域變數,不可作為欄位、屬性、方法參數/返回類型(需用 object 或 dynamic 傳遞) |