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

C# 介面成員限制與類別vs結構體差異:值型別與參考型別的核心抉擇

     編輯:關於C語言

介面可包含的成員類型

  • ✅ 方法、屬性、事件、索引子
  • ❌ 常數、欄位、運算子、建構函式、解構函式、靜態成員(C# 8.0 前)
  • C# 8.0+:可包含預設實作的方法、屬性、索引子、static 成員(私有/公開)、private 方法

類別 vs 結構體:核心差異對照

維度類別結構體
型別分類參考型別值型別
記憶體配置堆積堆疊(或內嵌於物件/陣列)
指派行為複製參考(共用實例)複製值(產生獨立副本)
預設值null所有欄位為 0/false/null
繼承單一繼承,可繼承/被繼承不可繼承類別/結構,可實作介面
建構函式參數化/無參數皆可無參數建構函式隱含存在,不可自定;可定義參數化
解構函式支援不支援
Null 可用性天然可為 null需 Nullable<T> 或 T?
封箱/解箱無轉為 object/介面時發生

實戰範例:點幾何物件設計


using System;

interface IPoint {
    double X { get; set; }
    double Y { get; set; }
    double Z { get; set; }
}

// 結構體:輕量、不可變、高效能
struct Point : IPoint {
    private readonly double _x, _y, _z;
    public Point(double x, double y, double z) { _x = x; _y = y; _z = z; }
    public double X { get => _x; set => throw new NotSupportedException("不可變"); }
    public double Y { get => _y; set => throw new NotSupportedException("不可變"); }
    public double Z { get => _z; set => throw new NotSupportedException("不可變"); }
}

// 類別:複雜邏輯、身分識別、可變狀態
class PointGeometry {
    private Point _value;
    public PointGeometry(double x, double y, double z) => _value = new Point(x, y, z);
    public PointGeometry(Point value) => _value = value; // 值複製

    public double X { get => _value.X; set => _value = new Point(value, _value.Y, _value.Z); }
    public double Y { get => _value.Y; set => _value = new Point(_value.X, value, _value.Z); }
    public double Z { get => _value.Z; set => _value = new Point(_value.X, _value.Y, value); }

    public static PointGeometry operator +(PointGeometry a, PointGeometry b)
        => new PointGeometry(a.X + b.X, a.Y + b.Y, a.Z + b.Z);

    public override string ToString() => $"X: {_value.X}, Y: {_value.Y}, Z: {_value.Z}";
}

class Program {
    static void Main() {
        Point p = new Point(1, 2, 3);
        PointGeometry g1 = new PointGeometry(p);
        PointGeometry g2 = new PointGeometry(p);
        g2.X = 4; g2.Y = 5; g2.Z = 6;
        Console.WriteLine(g1); // 1,2,3 (值複製,互不影響)
        Console.WriteLine(g2); // 4,5,6

        PointGeometry g3 = g1; // 參考複製
        g1.X = 7; g1.Y = 8; g1.Z = 9;
        Console.WriteLine(g1); // 7,8,9
        Console.WriteLine(g3); // 7,8,9 (同一實例)
        Console.ReadLine();
    }
}

輸出結果


X: 1, Y: 2, Z: 3
X: 4, Y: 5, Z: 6
X: 7, Y: 8, Z: 9
X: 7, Y: 8, Z: 9

選擇指南:何時用結構體?

  • ✅ 單一數值邏輯單元(Point、Vector、DateTime、Guid、Decimal)
  • ✅ 大量陣列/集合元素(減少堆積壓力、提升快取命中率)
  • ✅ 不可變資料傳遞(避免防禦性複製)
  • ✅ 高頻建立/銷毀(避免 GC 壓力)

選擇指南:何時用類別?

  • ✅ 複雜業務邏輯、狀態機、生命週期管理
  • ✅ 需要繼承/多型行為
  • ✅ 身分識別語意(同一實例代表同一實體)
  • ✅ 需要 null 表示「不存在」
  • ✅ 實作介面時避免封箱(介面參考會封箱結構體)

效能迷思澄清

  • 結構體不一定更快:大型結構體(>16 bytes)參數傳遞、回傳、介面轉換會產生大量複製/封箱開銷
  • readonly 結構體:C# 7.2+ readonly struct 避免防禦性複製,編譯器保證不修改
  • ref struct:C# 7.2+ ref struct 僅能棧上分配(如 Span<T>),極致效能
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved