在 C# 中,?屬性(Property)? 是類或結構體中的成員,用于封裝對私有字段(稱為 ?backing field?)的訪問,提供更靈活和安全的數據操作方式。屬性通過 get 和 set 訪問器控制對數據的讀寫,是面向對象編程中封裝思想的核心實踐。
屬性的核心作用?
- 封裝數據?:隱藏類的內部字段,通過屬性暴露可控的訪問接口。
- 驗證邏輯?:在 set 訪問器中添加數據驗證邏輯。
- 計算屬性?:動態生成值(例如根據其他字段計算)。
- 簡化語法?:自動屬性(Auto-Implemented Properties)讓代碼更簡潔。
?屬性的基本語法?
public class Person
{// 私有字段(backing field)private string _name;// 屬性:控制對 _name 的讀寫public string Name{get { return _name; }set { _name = value?.Trim(); } // 示例:自動去除空格}
}
?屬性的常見類型?
1. ?自動實現屬性(Auto-Implemented Property)?
不需要手動定義 backing field,編譯器自動生成。
public int Age { get; set; } // 默認可讀寫
public string Id { get; } // 只讀屬性(只能在構造函數中賦值)
2. ?計算屬性(Computed Property)?
根據其他字段動態返回值:
public class Rectangle
{public double Width { get; set; }public double Height { get; set; }// 計算面積(只讀)public double Area => Width * Height;
}
3. ?帶有驗證的屬性?
在 set 訪問器中添加邏輯:
private int _age;
public int Age
{get => _age;set{if (value < 0)throw new ArgumentException("年齡不能為負數!");_age = value;}
}
4. ?表達式體屬性(C# 6+)?
簡化單行邏輯的屬性:
public string FullName => $"{FirstName} {LastName}";
5. ?Init-only 屬性(C# 9+)?
只能在對象初始化時賦值:
public string Name { get; init; }
// 使用:
var person = new Person { Name = "Alice" }; // 合法
person.Name = "Bob"; // 編譯錯誤!
?屬性 vs 字段?
?字段(Field)? | ?屬性(Property)? |
---|---|
直接暴露數據,無訪問控制。 | 封裝數據,通過 get/set 控制訪問。 |
無法添加驗證或邏輯。 | 支持數據驗證、動態計算等。 |
例如:public string Name; | 例如:public string Name { get; set; } |
最佳實踐?
1?、優先使用屬性?:避免直接暴露公有字段。
2?、保持屬性簡單?:避免在屬性中編寫復雜邏輯(應交給方法)。
?3、只讀屬性?:若數據不應被外部修改,使用 { get; private set; } 或 init。
?4、線程安全?:在屬性中處理多線程訪問時需加鎖。
?示例:完整用法?
public class User
{private string _email;public string Email{get => _email;set{if (string.IsNullOrEmpty(value) || !value.Contains("@"))throw new ArgumentException("郵箱格式無效!");_email = value;}}// 自動屬性 + 默認值public DateTime CreatedAt { get; } = DateTime.Now;
}// 使用:
var user = new User();
user.Email = "test@example.com"; // 合法
user.Email = "invalid"; // 拋出異常
掌握屬性是 C# 開發的基礎,它能顯著提升代碼的可維護性和健壯性。