CodeGym /課程 /C# SELF /C# 裡的結構(struct)

C# 裡的結構(struct)

C# SELF
等級 10, 課堂 2
開放

1. 前言

結構(struct) 是 C# 裡一種特別的資料型別,可以把幾個值(甚至不同型別)組合成一個「盒子」。有點像小型 LEGO 組合:你把零件拼起來,最後得到一個方便又精簡的物件。

Struct 跟 class 很像,但有一些差異,通常用在比較「簡單」的情境,不需要 class 那麼強大又「重」的時候。

語法


struct Point
{
    public int X;
    public int Y;
}
宣告 Point 結構

這個例子裡我們描述了一個平面上的點,座標是 X 跟 Y。

結構通常用在哪?

大多數時候,struct 都是用來裝一些小型、簡單的資料物件,這些物件要很輕量、就是「純資料」。

C# 裡有些標準型別本身就是 struct:

  • int、double、bool、DateTime、TimeSpan、decimal、Guid
  • 甚至像 ConsoleKeyInfo 或 Point(在圖形函式庫裡)也是 struct

struct 跟 class 的差異

比較項目 結構(struct) 類別(class)
關鍵字
struct
class
儲存型態 Value Type Reference Type
存放位置 Stack(記憶體區域) Heap(記憶體區域)
傳遞給方法 值傳遞(複製一份) 參考傳遞
繼承 不行(只能實作 interface) 可以
能不能是 null 不行(只能用 Nullable) 可以
預設值 所有欄位自動初始化為 0 只能透過建構子

2. 結構的宣告與使用

你可以在 class 裡面或外面宣告 struct:


struct Rectangle
{
    public int Width;
    public int Height;
}

建立和使用 struct:

Rectangle r;
r.Width = 10;
r.Height = 5;
Console.WriteLine($"面積: {r.Width * r.Height}");

你也可以用建構子來初始化:

struct Point
{
    public int X;
    public int Y;

    // 建構子
    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }
}

var p = new Point(3, 7);
Console.WriteLine($"點: ({p.X}, {p.Y})");

什麼時候適合用 struct?

  • 用來裝小型的資料組合(像是座標、顏色、範圍、日期時間)。
  • 當你很在意效能跟記憶體(例如陣列裡有上百萬個點)。
  • 當這個物件應該像一個值(copy-paste 會真的複製一份!)。

如果你的物件:

  • 很大(欄位很多)。
  • 需要繼承結構。
  • 常常要用 reference 來改變。

那就不適合用 struct。

3. struct 的特性與「陷阱」

複製

Point p1 = new Point(1, 2);
Point p2 = p1; // 這裡會產生一份「複製品」!
p2.X = 100;

Console.WriteLine(p1.X); // 1 — 沒變!
Console.WriteLine(p2.X); // 100
複製 struct 會產生獨立的副本

預設值是自動給的

Point p; // X 跟 Y 都會自動是 0,就算你沒指定!

可以是 Nullable

如果你想讓 struct 可以存 null,要用特殊的 nullable 語法——型別名稱後面加個問號。這樣你就能把 null 指派給變數。

Point? p = null;
if (p == null)
    Console.WriteLine("沒有點");

4. 有自動屬性和方法的 struct

Struct 也可以有方法、屬性、事件,甚至 static 成員。

public struct Range
{
    public int Start { get; set; }
    public int End { get; set; }

    public int Length => End - Start;

    public override string ToString() => $"[{Start}..{End}]";
}

範例:複數的 struct

這是一個複數的 struct,有方法跟覆寫 ToString()


        struct Complex
{
    public double Re;
    public double Im;

    public Complex(double re, double im)
    {
        Re = re;
        Im = im;
    }

    public double Abs() => Math.Sqrt(Re * Re + Im * Im);

    public override string ToString() => $"{Re} + {Im}i";
}

var z = new Complex(1, 2);
Console.WriteLine(z);          // 1 + 2i
Console.WriteLine(z.Abs());    // 2.236...
2
任務
C# SELF, 等級 10, 課堂 2
上鎖
建立一個簡單的結構來儲存點的座標
建立一個簡單的結構來儲存點的座標
2
任務
C# SELF, 等級 10, 課堂 2
上鎖
有建構函式和計算面積方法的結構
有建構函式和計算面積方法的結構
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION