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

C# 屬性存取私有成員完整指南:封裝、效能與進階技巧

     編輯:關於C#

三種存取私有成員方式比較

方式封裝性安全性程式碼簡潔度效能
改為 public 欄位❌ 破壞❌ 直接暴露✅ 最簡單最快 (直接記憶體存取)
Getter/Setter 方法✅ 保持✅ 可驗證❌ 冗長方法呼叫開銷
**屬性**✅ 保持✅ 可驗證✅ **語法糖簡潔****JIT 內聯 → 接近欄位速度**

屬性基本語法與 IL 實現


private string _name;
public string Name 
{ 
    get => _name; 
    set => _name = value ?? throw new ArgumentNullException(nameof(value)); 
}

// 編譯器產生對應方法 (IL)
.get instance string Class::get_Name()
.set instance void Class::set_Name(string)
// JIT 會將這兩個方法內聯,消除呼叫開銷

進階屬性模式

1. 索引器 (支援多參數、多型別)


public class DataTable
{
    private List _rows = new();
    public Row this[int index] 
    { 
        get => _rows[index]; 
        set => _rows[index] = value; 
    }
    // 多參數
    public Cell this[int row, string colName] 
    { 
        get => _rows[row].Cells[colName]; 
        set => _rows[row].Cells[colName] = value; 
    }
}

2. 執行緒安全屬性 (鎖定)


private string _config;
private readonly object _lock = new();
public string Config
{
    get { lock (_lock) return _config; }
    set { lock (_lock) _config = value; }
}
// 或 .NET 4.7+ 使用互斥體更輕量
// 讀多寫少考慮 ReaderWriterLockSlim

3. 介面實作區分唯讀/可寫 (不推薦,破壞一致性)

同一類別實作 IReadOnly{ string Name { get; } } 和 IWritable{ string Name { get; set; } } 會造成介面轉型時行為不同,**不建議使用**。

關鍵設計原則

參考型別回傳防禦性複製


public class Person
{
    private Address _address;
    public Address Address 
    { 
        get => _address?.Clone(); // 回傳副本,防止外部修改內部狀態
        set => _address = value?.Clone(); 
    }
}

public class Address : ICloneable
{
    public string City { get; set; }
    public object Clone() => MemberwiseClone(); // 淺層複製足夠 (字串不可變)
}

**原則**:屬性回傳可變參考型別時,**務必回傳副本** (Clone/ToArray/ToList/new List(...)),否則呼叫端可繞過 setter 直接修改內部狀態。

Setter 參數驗證


public int Age
{
    get => _age;
    set 
    {
        if (value < 0 || value > 150) throw new ArgumentOutOfRangeException(nameof(value));
        _age = value;
    }
}

屬性是**外部修改內部狀態的唯一入口**,驗證邏輯集中於此,保證物件不變條件。

自動實作屬性 (C# 3+) 與 init (C# 9+)


// 傳統自動屬性 (編譯器產生隱藏 backing field)
public string Name { get; set; }

// 唯讀自動屬性 (建構函式/物件初始化器可指定)
public string Id { get; init; }

// 唯讀 + 預設值
public DateTime CreatedAt { get; init; } = DateTime.UtcNow;

效能補充

  • JIT 內聯使屬性存取**等同欄位存取速度** (奈秒級差異)。
  • 避免在 getter 執行複雜運算/IO (違反最小驚訝原則),若需計算請用方法 GetComputedValue()。
  • readonly struct 的自動屬性 getter 會被 JIT 積極內聯與優化。

總結

**屬性是 C# 封裝的核心機制** — 兼具欄位語法簡潔性、方法驗證彈性、JIT 內聯效能。遵循「回傳參考型別需複製、Setter 必驗證、複雜計算用方法」三原則,即能設計出健壯、可維護的類別 API。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved