C# --- Field and Property
- 字段 (Field) vs. 屬性 (Property)
- Property的聲明初始化方法
- 單例類property錯誤初始化導致線程泄漏
字段 (Field) vs. 屬性 (Property)
字段 (Field) - 數據的存儲容器
- 字段是直接在類或結構中聲明的變量。它是存儲數據的地方,是對象狀態的核心組成部分。
- 目的:純粹用于數據存儲。
- 訪問控制:通過訪問修飾符(如 public, private, internal) 來控制誰可以訪問這個存儲容器。
- 關鍵點:根據面向對象的最佳實踐,字段應該幾乎總是 private 的,將其視為類的內部實現細節。將其暴露為 public 破壞了封裝性,是不推薦的做法。
public class Person
{// 私有字段 - 正確的做法private string _name;private int _age;// 公共字段 - 極其不推薦!任何代碼都可以隨意修改,無法控制。public string NickName;
}
屬性 (Property) - 數據的訪問控制器
- 屬性是一種特殊的類成員,它提供了對私有字段進行讀取、寫入或計算的靈活機制。它本質上是兩個特殊方法(get 和 set 訪問器)的包裝。
- 目的:控制對字段的訪問。它對外提供一個像字段一樣簡單的訪問接口,但在內部你可以實現復雜的邏輯。
- 優勢:
- 封裝:將數據的存儲(私有字段)和數據的訪問(公共屬性)分離。
- 數據驗證:可以在 set 訪問器中驗證數據的有效性。
- 計算能力:可以在 get 訪問器中返回計算后的值。
- 精細訪問控制:可以分別設置 get 和 set 的訪問級別。
public class Person
{// 私有后備字段 (Private backing fields)private string _name;private int _age;// 公共屬性 (Public Properties)public string Name{get { return _name; }set {if (!string.IsNullOrWhiteSpace(value))_name = value;}}public int Age{get { return _age; }set {if (value >= 0 && value <= 120) // 數據驗證_age = value;elsethrow new ArgumentException("Invalid age.");}}// 計算屬性:沒有后備字段,值由其他字段計算得出public string Description{get { return $"{Name} is {Age} years old."; }}
}
Property的聲明初始化方法
完整屬性聲明(Full Property)
- 這是最傳統、最詳細的屬性聲明方式,顯式地定義了后備字段和訪問器邏輯。
private string _name; // 后備字段public string Name
{get { return _name; }set { _name = value; }
}
自動屬性(Auto-Implemented Property)
- C# 3.0 引入的簡潔語法,編譯器會自動生成隱藏的后備字段。
public string Name { get; set; }
只讀自動屬性(Read-Only Auto-Property)
- C# 6.0 引入的語法,只能在構造函數中初始化。
public string Id { get; } // 只能在構造函數中賦值public MyClass(string id)
{Id = id;
}
自動屬性初始化器(Auto-Property Initializer)
- C# 6.0 引入,允許在聲明時為自動屬性提供默認值。
public string Name { get; set; } = "Unknown";
public int Age { get; set; } = 18;
public List<string> Items { get; set; } = new List<string>();
表達式主體屬性(Expression-Bodied Property)
- C# 7.0 引入,使用 Lambda 表達式語法 (=>) 定義只讀屬性。
public string FullName => $"{FirstName} {LastName}";
public double Area => Width * Height;
public bool IsValid => !string.IsNullOrEmpty(Name) && Age > 0;
Init-only 屬性(Init-Only Property)
- C# 9.0 引入,允許在對象初始化期間設置屬性值,之后變為只讀。
public string Name { get; init; }
public int Age { get; init; }// 使用對象初始化器
var person = new Person { Name = "Alice", Age = 25 };
具有不同訪問級別的屬性
- 可以為 get 和 set 訪問器設置不同的訪問修飾符。
// 公共獲取,內部設置
public string Name { get; internal set; }// 公共獲取,私有設置
public int Age { get; private set; }// 受保護的獲取,私有設置
public string Details { get; protected set; }
單例類property錯誤初始化導致線程泄漏
單例類property錯誤初始化導致線程泄漏