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

[你必須知道的.NET] 第四回:class 與 struct 深度比較(二):經典範例、.NET Framework 實作、結論

     編輯:關於C語言

四、經典範例完整解析

1. 定義介面

interface IPerson
{
    void GetSex();
}

2. 定義類別

public class Person
{
    public Person() { }
    public Person(string name, int age) { _name = name; _age = age; }
    
    private string _name;
    public string Name { get { return _name; } set { _name = value; } }
    
    private int _age;
    public int Age { get { return _age; } set { _age = value; } }
}

3. 定義結構

struct Family : IPerson  // 可實作介面,不可繼承類別/結構
{
    public string Name;
    public int Age;
    public bool Sex;
    public string Country;
    public Person Person; // 參考類別欄位
    
    // 無參建構函式:結構不允許顯式定義
    // 建構函式必須有參數
    public Family(string name, int age, bool sex, string country, Person person)
    {
        Name = name; Age = age; Sex = sex; Country = country; Person = person;
    }
    
    // 實作介面方法
    public void GetSex()
    {
        if (Sex)
            Console.WriteLine(Person.Name + " is a boy.");
        else
            Console.WriteLine(Person.Name + " is a girl.");
    }
    
    public void ShowPerson()
    {
        Console.WriteLine("This is {0} from {1}", new Person(Name, 22).Name, Country);
    }
    
    // 可覆寫 Object 虛擬方法
    public override string ToString()
    {
        return String.Format("{0} is {1}, {2} from {3}", Person.Name, Age, Sex ? "Boy" : "Girl", Country);
    }
}

4. 測試程式碼與輸出分析

static void Main()
{
    Person p = new Person("Tom", 25);
    Family f = new Family("Tom", 25, true, "USA", p);
    
    Console.WriteLine("f.GetSex():");
    f.GetSex(); // Tom is a boy.
    
    Console.WriteLine("\nf.ShowPerson():");
    f.ShowPerson(); // This is Tom from USA
    
    Console.WriteLine("\nf.ToString():");
    Console.WriteLine(f.ToString()); // Tom is 25, Boy from USA
    
    Console.WriteLine("\n--- 複製語意測試 ---");
    Family f2 = f; // 值複製:完全獨立副本
    f2.Name = "Jerry";
    Console.WriteLine($"f.Name={f.Name}, f2.Name={f2.Name}"); // f.Name=Tom, f2.Name=Jerry
    
    Person p2 = p; // 參考複製:指向同一物件
    p2.Name = "Jerry";
    Console.WriteLine($"p.Name={p.Name}, p2.Name={p2.Name}"); // p.Name=Jerry, p2.Name=Jerry
}

五、.NET Framework 實作研究

.NET 基底類別庫中,多數基礎型別實作為 struct:

為什麼 Point 是 struct?

  • 典型用法:Point[] points = new Point[10000] → 連續記憶體、無物件頭、GC 壓力極低
  • 若為 class:10000 個獨立物件、各有 Object Header、散佈堆積、GC 掃描成本高
  • 語意:座標點屬於「值」,複製即獨立,符合值型別語意

六、結論與討論題

核心結論

  1. 本質差異:class = 參考型別(堆積),struct = 值型別(堆疊/內嵌)
  2. 語意差異:class 表達「實體/行為」,struct 表達「資料結構/值」
  3. 效能權衡:struct 避免堆積分配與 GC,但大型 struct 傳遞有複製成本
  4. 設計原則:預設用 class,符合以下條件才考慮 struct:
    • 主要儲存資料、行為極少
    • 實例大小 < 16 位元組(建議)
    • 不可變或值語意明確
    • 大量陣列/集合分配
    • 需與非受控代碼互通

討論題

  1. struct 還主要應用在哪些方面?
    • 數值型別、幾何結構、日期時間、資料庫資料列映射、高效能計算陣列、Interop 結構
  2. C++ vs C# struct 差異?
    • C++:struct 預設 public、可繼承、可虛擬函數、本質同 class
    • C#:struct 值型別、不可繼承、無預設建構函式、密封、無虛擬方法
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
類型實作理由
System.Int32, Double, Boolean 等struct頻繁使用、值語意、效能關鍵
System.Drawing.Point, Size, Rectanglestruct輕量幾何結構、大量陣列分配
System.DateTime, TimeSpanstruct不可變值型別、高頻運算
System.Guidstruct16 位元組、值語意、避免堆積分配
System.Nullable<T>struct包裝值類別加上 null 狀態