C# 3.0 之前,定義一個公開屬性需要:私有欄位 + 公開屬性 + get/set 存取子:
class Person
{
private int _age;
private string _name;
public int Age
{
get { return _age; }
set { _age = value; }
}
public string Name
{
get { return _name; }
set { _name = value; }
}
}
雖然 get/set 可放入業務邏輯,但絕大多數情況只是單純讀寫欄位。為商業實體類別定義幾十個屬性時,重複勞動極其繁瑣。
C# 3.0 讓我們只寫「簽章」,編譯器自動補齊後端欄位與存取子:
class Employee
{
// public string Name { get; } // 錯誤:必須有 set
public string Name { get; set; }
public int Age { get; private set; } // 非對稱存取層級
public Employee(string name, int age)
{
this.Name = name;
this.Age = age;
}
}
優點顯而易見:程式碼精簡、可讀性高、維護容易。
C# 3.0 特性純屬語言/編譯器層面,不依賴 .NET Framework 新版本。編譯器為我們生成了完整的後端欄位與屬性實作。反編譯觀察:
internal class Employee
{
// Fields
[CompilerGenerated]
private int <Age>k__BackingField;
[CompilerGenerated]
private string <Name>k__BackingField;
// Methods
public Employee(string name, int age);
// Properties
public int Age { get; private set; }
public string Name { get; set; }
}
<PropertyName>k__BackingField 側寫欄位,標記 [CompilerGenerated]。get/set 直接存取此欄位,行為與手寫版本完全一致。思考:自動屬性的後端欄位能否透過反射存取?命名規則 <Name>k__BackingField 是否保證不衝突?