通訊錄記錄含姓名、電話、地址。用簡單型別需三個變數管理,不直觀。結構將相關變數組織為單一實體。
struct PhoneBook
{
public string Name;
public string Phone;
public string Address;
}
PhoneBook p1;
p1.Name = "Mike";
p1.Phone = "0912-345678";
p1.Address = "Taipei";
struct 關鍵字宣告變數.成員public 表公開存取權限struct Address
{
public string City;
public string Street;
public uint No;
}
struct PhoneBook
{
public string Name;
public uint Age;
public string Phone;
public Address Address; // 結構作為成員型別
}
// 使用
PhoneBook pb;
pb.Address.City = "Taipei";
pb.Address.Street = "Renai Rd";
pb.Address.No = 100;
| 特性 | struct (值型別) | class (參考型別) |
|---|---|---|
| 記憶體配置 | Stack(區域變數)/ Inline(陣列/欄位) | Heap |
| 指派行為 | 複製整個實體 | 複製參考 |
| 預設值 | 所有欄位為 0/null/false | null |
| 繼承 | 不可繼承類別,可實作介面 | 單一繼承 |
| 建構函式 | 不可定義無參建構函式(C# 10 前) | 可定義任意建構函式 |
| 解構函式 | 不可定義 | 可定義 |
| null 值 | 不可為 null(除非 Nullable<T>) | 可為 null |
Point、Vector、DateTime、GuidPoint[] 連續記憶體,無參考間接層,Cache 友善readonly、屬性唯讀object/介面使用IEquatable<T>:避免裝箱比較struct 節省記憶體?→ 區域變數是,但頻繁當參數傳遞/裝箱反而較重readonly struct Point3D // 編譯器強制不可變
{
public readonly double X, Y, Z;
public Point3D(double x, double y, double z) => (X, Y, Z) = (x, y, z);
}
ref struct SpanWrapper // 僅能棲息於 Stack,不可裝箱、不可作為類別欄位
{
public Span<byte> Data;
}
結構是值型別封裝利器,適用於小型、不可變、高頻資料。善用 readonly struct、ref struct 發揮極致效能,避免濫用導致複製成本與裝箱開銷。