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

C# 結構體與類別巢狀定義完整指南:陣列初始化與實例化細節

     編輯:關於C語言

前言

C# 中結構體 (struct) 與類別 (class) 皆可作為巢狀資料容器,但兩者在記憶體模型、預設建構函式、陣列初始化行為上有關鍵差異。本文透過實際程式碼對比,釐清 結構體需手動初始化陣列元素、類別可在建構函式自動完成 等核心觀念。

案例場景

定義一張「報銷單」主檔 CWSData,包含標題、企業代碼與明細陣列 CWSDataTM[];明細項目含順序號、報銷號、單據張數。

方式一:結構體巢狀

定義

public struct CWSData
{
    public string strTitle;       // 標題
    public string strQYCode;      // 企業代碼
    public CWSDataTM[] cDetailItems; // 明細陣列
}

public struct CWSDataTM
{
    public string strSXH; // 順序號
    public string strBXH; // 報銷號
    public string strDJS; // 單據張數
}

使用方式 - 必須手動 new 陣列與每個元素

int M = 3;
CWSData cwData = new CWSData();        // 結構體預設建構函式:所有欄位歸零/null
cwData.cDetailItems = new CWSDataTM[M]; // 僅配置陣列參考,元素仍為預設值 (null/0/false)

// 逐一指派值
cwData.cDetailItems[0].strSXH = "1";
cwData.cDetailItems[0].strBXH = "BX001";
cwData.cDetailItems[0].strDJS = "5";
// ... 其餘元素同理

關鍵特性

  • 實質型別:儲存在堆疊 (或內含物件的堆疊欄位),指派即複製整個實例。
  • 無自訂無參數建構函式:C# 禁止 struct 定義 public CWSData(),故無法在定義處自動 new 陣列元素。
  • 陣列元素為實質型別:new CWSDataTM[M] 產生的是 M 個已初始化為零的 CWSDataTM 實例,而非 null 參考。但若巢狀層級含 string 等參考型別,該欄位仍為 null。

方式二:類別巢狀

定義

public class CWSData
{
    public string strTitle;
    public string strQYCode;
    public CWSDataTM[] cDetailItems;

    public CWSData(int m) // 自訂建構函式
    {
        if (m > 0)
        {
            cDetailItems = new CWSDataTM[m];
            for (int i = 0; i < m; i++)
                cDetailItems[i] = new CWSDataTM(); // 明確實例化每個元素
        }
    }
}

public class CWSDataTM
{
    public string strSXH;
    public string strBXH;
    public string strDJS;

    public CWSDataTM() { } // 可定義無參數建構函式
}

使用方式 - 建構函式封裝初始化邏輯

int M = 5;
CWSData cwData = new CWSData(M); // 一次完成陣列配置與元素實例化

for (int i = 0; i < M; i++)
{
    cwData.cDetailItems[i].strSXH = "aaa";
    // ...
}

關鍵特性

  • 參考型別:變數儲存堆積物件參考,指派僅複製參考。
  • 建構函式彈性:可在建構函式執行任意初始化邏輯 (配置陣列、實例化元素、設定預設值)。
  • GC 壓力較大:每個 new CWSDataTM() 產生獨立堆積物件,大量資料時需考慮效能。

比較總結表

特性結構體類別
記憶體配置堆疊 / 內含於父物件堆積
指派語意值複製參考複製
無參數建構函式隱含、不可覆寫可自訂
陣列元素初始化自動零初始化需手動 new 每個元素
適用場景小型、不可變、高效能資料結構複雜物件、需繼承、參考語意

進階建議

  • 結構體不可變模式:所有欄位 readonly、透過建構函式 (C# 10+ 允許 struct 定義有參數建構函式) 初始化,避免防禦性複製。
  • 類別搭配集合:實務上明細列建議用 List<CWSDataTM> 取代陣列,彈性擴充並避免預先決定大小。
  • 序列化考量:結構體若含參考型別欄位 (如 string),XML/JSON 序列化行為與類別一致;二進位序列化需注意記憶體佈局。

完整可執行範例

using System;

namespace NestedDemo
{
    // 結構體版
    public struct StructMain { public string Title; public StructSub[] Items; }
    public struct StructSub { public string Code; public int Qty; }

    // 類別版
    public class ClassMain
    {
        public string Title;
        public ClassSub[] Items;
        public ClassMain(int count)
        {
            Items = new ClassSub[count];
            for (int i = 0; i < count; i++) Items[i] = new ClassSub();
        }
    }
    public class ClassSub { public string Code; public int Qty; }

    class Program
    {
        static void Main()
        {
            // 結構體
            var s = new StructMain { Title = "Struct", Items = new StructSub[2] };
            s.Items[0].Code = "A001"; // 直接指派,Items[0] 已零初始化

            // 類別
            var c = new ClassMain(2) { Title = "Class" };
            c.Items[0].Code = "B001"; // 建構函式已 new ClassSub()

            Console.WriteLine($"{s.Title}: {s.Items[0].Code}");
            Console.WriteLine($"{c.Title}: {c.Items[0].Code}");
        }
    }
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved