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

Effective C# 原則 6:區別實值型別與參考型別(下)

     編輯:關於C語言

記憶體配置差異實測

public class Container
{
    private MyType _a = new MyType();
    private MyType _b = new MyType();
}

// MyType 為 struct(實值型別):
// 1 次堆積配置,大小 = 2 × sizeof(MyType)

// MyType 為 class(參考型別):
// 3 次堆積配置:
//   - Container 物件(含 2 個參考,8 bytes × 2 = 16 bytes)
//   - _a 物件
//   - _b 物件

陣列配置對比

MyType[] arr = new MyType[100];

// 實值型別:1 次配置,連續記憶體,100 × sizeof(MyType)
// 參考型別:1 次配置參考陣列(100 × 8 bytes),所有元素為 null
//           需再 100 次配置實際物件 → 101 次配置、記憶體碎片、GC 壓力大

設計決策:實值型別存資料、參考型別表達行為

// 實值型別:資料容器,不可變最佳
public readonly struct Point3D
{
    public double X { get; }
    public double Y { get; }
    public double Z { get; }
    public Point3D(double x, double y, double z) => (X, Y, Z) = (x, y, z);
}

// 參考型別:行為實體,支援多型
public abstract class Shape
{
    public abstract double Area { get; }
    public virtual void Draw() { ... }
}

public class Circle : Shape
{
    public double Radius { get; }
    public override double Area => Math.PI * Radius * Radius;
}

從 struct 變更為 class 的破壞性影響

// v1: struct
public struct Employee
{
    public string Name;
    public decimal Salary;
    public void Pay(BankAccount a) => a.Deposit(Salary);
}

// v2: class(加入繼承)
public class Employee
{
    public string Name { get; set; }
    public decimal Salary { get; set; }
    public virtual void Pay(BankAccount a) => a.Deposit(Salary);
}

// 影響:
// - 指派語意從複製變為參考共享
// - null 成為合法值,需防禦性檢查
// - 等價比較從結構相等變為參考相等
// - 陣列/集合記憶體模型完全不同
// - 所有呼叫端需重新編譯(二進位不相容)

決策檢查清單

特徵傾向 struct傾向 class
主要用途資料封裝行為/服務
不可變是視情況
大小< 16 bytes任意
頻繁陣列/集合是否
需繼承/多型否是
需 null 語意否是
身分識別重要否是
高頻複製/傳遞是否

核心原則

預設選擇 class。只有明確需要實值語意(複製、不可變、高效能陣列)且符合上表特徵時,才用 struct。 變更決定成本極高,設計階段務必審慎評估。

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