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

C# 兩大核心設計原則深度探討:屬性封裝與值/參考型別選擇

     編輯:關於C#

《Effective C#》提出許多實用準則,其中「優先使用屬性而非公開欄位」與「明辨值類型與參考型別使用場合」是類別設計的基石。本文深度剖析這兩原則的適用邊界、效能迷思與實務決策框架。

原則一:優先使用屬性封裝資料成員

為什麼需要屬性?

理由說明
驗證與副作用setter 可加入範圍檢查、觸發事件、記錄日誌、延遲初始化
執行緒同步getter/setter 內部可加 lock 或使用 Interlocked
虛擬/抽象/介面屬性可 virtual/abstract/override,欄位不行 → 多態契約關鍵
二進位相容性將欄位改為屬性**不需重新編譯呼叫端** (JIT 內聯),欄位改屬性屬原始碼相容但非二進位相容
不同存取層級public get; private set;、protected set; 等靈活控制
序列化/繫結/反射大多數框架 (JSON、XML、DataBinding、EF) 僅識別屬性,忽略欄位

效能迷思破解

  • JIT 內聯:簡單 getter/setter (單指令、無例外、非虛擬) 會被 JIT 內聯,**零效能損失**。
  • 不內聯情況:虛擬屬性、方法體過大 (>32 bytes IL)、複雜控制流、含 try/catch。這些情況下直接存取欄位也無法內聯 (虛擬調用本身即不可內聯)。
  • 結論:除非極度熱路徑 (如遊戲核心迴圈、數學庫),否則**永遠優先用屬性**,可維護性遠大於微乎其微的理論開銷。

何時可用公開欄位?

  • 單純資料傳輸物件 (DTO)、**不可變結構體** (readonly struct)、高效能數學向量/矩陣、Interop 需固定記憶體佈局 ([StructLayout])。
  • 即使是 DTO,建議用 public int Id { get; set; } 而非 public int Id;,避免日後框架相容問題。

原則二:值類型存資料、參考類型定行為

判斷清單:是否適合定義為 struct?

  1. 主要職責是**資料儲存** (無行為/邏輯)?
  2. 公開介面僅為**存取屬性**?
  3. **永不**需要繼承 (struct 隱性 sealed)?
  4. **永不**需要多態 (無虛擬方法、介面實作)?
  5. 實例大小 **< 16 bytes** (CLR 設計指導方針)?
  6. **高頻建立/銷毀/複製** (避免堆積配置/GC 壓力)?
  7. **不**會頻繁裝箱/拆箱 (或搭配泛型集合避免)?

**全勾 → 適合 struct**;**任何一項不符 → 應用 class**。

值類型效能陷阱

陷阱現象對策
裝箱/拆箱存入 ArrayList/object/介面 → 堆積配置 + 複製 + GC 壓力使用泛型 List<T>、介面約束 where T : struct
大型結構體複製參數傳遞、回傳值、集合索引皆整體複製 (memcpy),>16 bytes 成本顯著改 class、或 in/ref/out 參數、readonly struct 避免防禦性複製
防禦性複製readonly struct 透過 in 參數呼叫非 readonly 成員時,編譯器隱性複製整個結構所有成員標記 readonly、或改用 class

現代 C# 最佳實務 (C# 7.2+ / .NET Core)

  • 預設用 class:除非明確符合 struct 判斷清單,否則用 class 避免微妙 Bug。
  • readonly struct:不可變值類型,編譯器強制所有成員 readonly,消除防禦性複製。
  • ref struct:僅限棧分配 (Span<T>, Memory<T>),高效能緩衝區處理。
  • record struct (C# 10):不可變資料記錄,自動實作值相等性、with-expression、ToString。
  • 泛型專用化:List<Vector3> 零裝箱、記憶體連續、CPU 緩存友好 → 數學/遊戲/圖形首選 struct。

決策速查表

場景推薦理由
一般業務實體 (Entity/DTO/VO)class / record需繼承、多態、參考語義、框架相容
高效能數學/圖形/遊戲向量readonly struct / record struct值語義、零 GC、CPU 緩存友好、SIMD 友好
跨非受控邊界 (P/Invoke)struct + [StructLayout]記憶體佈局精確控制
大型資料結構 (>64 bytes)class複製成本高、防禦性複製風險
需實作介面/多態class / recordstruct 不能繼承、介面實作會裝箱
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved