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

Effective C# 原則 23:避免回傳內部物件參考,保護封裝邊界

     編輯:關於C#

「唯讀屬性」的陷阱

回傳參考型別的唯讀屬性,呼叫端仍可透過參考修改內部物件狀態:

public class MyBusinessObject {
    private DataSet _ds;
    public DataSet Data => _ds; // 唯讀屬性
}
// 呼叫端
var ds = bizObj.Data;
ds.Tables.Clear(); // 內部資料被清空!

封裝邊界被繞過,類別失去對狀態變更的控制權。

四大防護策略

  1. 實值型別:屬性回傳複本,呼叫端修改不影響內部狀態。
  2. 不可變型別:如 string,本質安全無法修改。
  3. 介面隔離:回傳僅暴露必要功能的介面(如 IListSource),隱藏具體實作方法。
  4. 包裝器/視圖模式:回傳受控視圖物件(如 DataView),限制可執行操作。

實務範例:DataView 受控視圖

public class MyBusinessObject {
    private DataSet _ds;
    public IList this[string tableName] {
        get {
            var view = _ds.DefaultViewManager.CreateDataView(_ds.Tables[tableName]);
            view.AllowNew = false;
            view.AllowDelete = false;
            view.AllowEdit = false;
            return view; // 回傳介面,非具體 DataView
        }
    }
}
// 呼叫端
IList dv = bizObj["customers"];
foreach (DataRowView r in dv) Console.WriteLine(r["name"]);

DataViewManager 建立視圖,屬性鎖定新增/刪除/編輯。回傳 IList 介面進一步限制存取權。

需開放修改時:實作觀察者模式

若業務需允許外部修改(如資料繫結編輯),類別應訂閱內部資料事件(RowChanging, RowChanged),在事件處理常式中驗證與回應變更,維持狀態一致性。

總結

  • 回傳參考型別等同洩漏內部狀態控制權。
  • 優先使用實值型別、不可變型別、介面隔離、受控視圖。
  • 必須開放修改時,建立事件驗證機制,掌握所有狀態變更。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved