首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> C# 入門

C# 運算子多載完整教學:語法、規則、比較運算子與實戰技巧

     編輯:C# 入門

C# 運算子多載完整教學:語法、規則、比較運算子與實戰技巧

C# 允許為使用者定義型別(類別、結構)重新定義內建運算子的行為,這稱為運算子多載。透過運算子多載,自訂型別能像內建型別一樣自然地進行數學運算、比較、邏輯判斷,大幅提升程式碼的可讀性與表達力。

運算子多載基本語法

運算子多載是特殊的 static 方法,命名規則為 operator <符號>:

public static Box operator +(Box left, Box right) {
    return new Box {
        Length = left.Length + right.Length,
        Width = left.Width + right.Width,
        Height = left.Height + right.Height
    };
}

關鍵規則:

  • 必須宣告為 public static
  • 至少一個參數必須是宣告該運算子的型別
  • 一元運算子有一個參數,二元運算子有兩個參數
  • 傳回型別可為任意型別(不限於宣告型別)

可多載與不可多載運算子對照表

類別可多載不可多載
一元運算子+ - ! ~ ++ -- true false—
二元運算子+ - * / %—
比較運算子== != < > <= >=—
邏輯運算子—&& ||(但可透過 & | false true 間接支援)
指派運算子—= += -= *= /= %=
其他—[] () ?. ?? => new typeof sizeof is as

注意:== 與 !=、< 與 >、<= 與 >= 必須成對多載,否則編譯器會發出警告。

完整實戰範例:Box 類別的運算子多載

public class Box {
    public double Length { get; set; }
    public double Width { get; set; }
    public double Height { get; set; }

    public double Volume => Length * Width * Height;

    // 加法:合併兩個箱子
    public static Box operator +(Box a, Box b) => new Box {
        Length = a.Length + b.Length,
        Width = a.Width + b.Width,
        Height = a.Height + b.Height
    };

    // 相等比較:必須成對實作 !=
    public static bool operator ==(Box a, Box b) {
        if (ReferenceEquals(a, b)) return true;
        if (a is null || b is null) return false;
        return a.Length == b.Length && a.Width == b.Width && a.Height == b.Height;
    }
    public static bool operator !=(Box a, Box b) => !(a == b);

    // 大小比較:成對實作
    public static bool operator <(Box a, Box b) => a.Volume < b.Volume;
    public static bool operator >(Box a, Box b) => a.Volume > b.Volume;
    public static bool operator <=(Box a, Box b) => a.Volume <= b.Volume;
    public static bool operator >=(Box a, Box b) => a.Volume >= b.Volume;

    // 覆寫 Equals/GetHashCode 配合 == 運算子
    public override bool Equals(object obj) => this == (obj as Box);
    public override int GetHashCode() => HashCode.Combine(Length, Width, Height);

    public override string ToString() => $"({Length}, {Width}, {Height}) Vol={Volume}";
}

測試與輸出

var box1 = new Box { Length = 6, Width = 7, Height = 5 };   // 體積 210
var box2 = new Box { Length = 12, Width = 13, Height = 10 }; // 體積 1560
var box3 = box1 + box2; // (18, 20, 15) 體積 5400

Console.WriteLine($"Box1: {box1}");
Console.WriteLine($"Box2: {box2}");
Console.WriteLine($"Box3 = Box1 + Box2: {box3}");

Console.WriteLine($"Box1 > Box2: {box1 > box2}");   // False
Console.WriteLine($"Box1 < Box2: {box1 < box2}");   // True
Console.WriteLine($"Box1 == Box3: {box1 == box3}"); // False

var box4 = box3;
Console.WriteLine($"Box3 == Box4: {box3 == box4}"); // True

輸出結果:

Box1: (6, 7, 5) Vol=210
Box2: (12, 13, 10) Vol=1560
Box3 = Box1 + Box2: (18, 20, 15) Vol=5400
Box1 > Box2: False
Box1 < Box2: True
Box1 == Box3: False
Box3 == Box4: True

進階技巧與注意事項

1. 隱式/顯式轉換運算子

雖非算術運算子,但 implicit / explicit 運算子同樣重要:

public struct Temperature {
    public double Celsius { get; }
    public Temperature(double c) => Celsius = c;

    public static implicit operator Temperature(double c) => new Temperature(c);
    public static explicit operator double(Temperature t) => t.Celsius;
    public static implicit operator Temperature(Fahrenheit f) => new Temperature((f.Value - 32) * 5/9);
}

2. 運算子多載與介面

介面不能宣告運算子多載(C# 11 引入 static abstract 除外)。若需在泛型限制中使用運算子,請使用 System.Numerics 中的介面(如 INumber<T>)。

3. 可為 Null 的型別考量

比較運算子應正確處理 null:

public static bool operator ==(Box a, Box b) {
    if (ReferenceEquals(a, b)) return true;
    if (a is null || b is null) return false;
    return a.Length == b.Length && a.Width == b.Width && a.Height == b.Height;
}

4. 效能考量

  • 運算子多載會建立新物件(如 + 回傳新 Box),頻繁使用可能增加 GC 壓力。
  • 結構體運算子多載避免堆疊配置,效能較佳。
  • 考慮提供 Add、Equals 等方法別名,供不支援運算子多載的語言使用。

最佳實踐總結

  • 語意一致性:+ 應代表加法/合併,== 應代表值相等,避免違反直覺的多載。
  • 成對實作:比較運算子必須成對,== 需配合 Equals/GetHashCode 覆寫。
  • 不可變型別:運算子多載回傳新實例,適合不可變型別設計。
  • 文件化:使用 XML 註解說明運算子行為、副作用、效能特徵。
  • 單元測試:驗證邊界條件(null、零值、極大值、相等性質:自反性、對稱性、傳遞性)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved