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

[你必須知道的 .NET] 第四回:Class 與 Struct 的記憶體模型、語法差異與選型指南

     編輯:關於C#

核心差異:參考型別 vs 實值型別

特性Class (Reference Type)Struct (Value Type)
基底類別System.ObjectSystem.ValueType → Object
記憶體配置Managed Heap (GC 管理)Thread Stack / Inline in containing object
變數內容參考 (位址)實際資料值
指派語意複製參考 (淺拷貝)複製值 (深拷貝)
Null 支援可為 null不可為 null (除非 Nullable<T>)
繼承單一繼承、介面、多型不可繼承類別、可實作介面、無多型
建構函式可無參、可自訂、可靜態建構函式不可無參、不可析構函式、隱含無參初始化為 0/null
關鍵字限制可 abstract/sealed/virtual/override/protected不可上述關鍵字,可覆寫 Equals/GetHashCode/ToString
傳遞參數傳參考 (預設)傳值 (預設),ref/out 可改為傳參考
銷毀時機GC 非確定性回收離開作用域立即釋放 (Stack) / 隨容器釋放

語法相似但語意迥異


// 介面實作:Struct 可實作介面,達到多型效果
interface IPerson { void GetSex(); }
struct Family : IPerson {
    public string Name; public int Age; public bool Sex; public string Country;
    public Person PersonRef; // 參考型別欄位
    public Family(string n, int a, bool s, string c, Person p) {
        Name=n; Age=a; Sex=s; Country=c; PersonRef=p;
    }
    public void GetSex() => Console.WriteLine($"{PersonRef.Name} is {(Sex?"boy":"girl")}");
    public override string ToString() => $"{PersonRef.Name} {Age} {(Sex?"Boy":"Girl")} {Country}";
}

效能考量:何時選 Struct?

  • 小型、不可變、邏輯單純:Point、DateTime、Guid、decimal
  • 大量陣列:Point[] 連續記憶體、無 GC 壓力、Cache 友善
  • 高頻建立/銷毀:避免 Gen 0 GC 壓力
  • Interop / P/Invoke:對應 C 結構體、Win32 API 參數

避坑指南

  1. 裝箱/拆箱:Struct 當作 object/介面使用會裝箱,頻繁發生效能災難
  2. 可變 Struct 邪教:struct Mutable { public int X; } 配合屬性回傳副本導致修改失效,Struct 應為不可變
  3. 遞迴結構:Struct 不能包含自身型別欄位(無限大小),需用 Class
  4. 預設值陷阱:new MyStruct() 與 default(MyStruct) 相同,所有欄位為 0/null,不可依賴建構函式初始化邏輯
  5. 介面呼叫裝箱:IPerson p = family; 發生裝箱,改用泛型約束 where T : IPerson 避免

.NET Framework 實例

  • System.Drawing.Point、Size、Rectangle:Struct,繪圖高頻運算
  • System.Guid:Struct,16 bytes,值語意
  • System.DateTime、DateTimeOffset、TimeSpan:Struct
  • System.Decimal:Struct,16 bytes,高精度數值
  • System.Nullable<T>:Struct 包裝實值型別可為 null

選型決策樹

是否需要繼承/多型/可為 null/參考語意? → Class
否 → 是否小型 (<=16 bytes)、不可變、大量陣列、Interop? → Struct
否 → Class (預設選擇,風險最小)

結語

Class 是面向物件的主力,Struct 是效能優化的利器。理解記憶體模型差異、避開可變 Struct 與裝箱陷阱,才能在正確場合發揮 Struct 的極致效能。下一回將探討「引用型別與實值型別的深度比較」。

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