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

C# 運算子多載實戰:一元/二元運算子、成對實作與角色升級範例

     編輯:關於C#

為什麼需要運算子多載?

讓自訂型別支援直觀的數學/邏輯運算符號 (如 v1 + v2、++player),提升程式碼可讀性與領域模型表達力。

一元運算子多載:角色升級系統


public class Player {
    public int Neili { get; private set; } = 10;
    public int Tili { get; private set; } = 50;
    public int Jingyan { get; private set; }
    public int NeiliMax { get; private set; } = 50;
    public int TiliMax { get; private set; } = 50;

    public static Player operator ++(Player p) {
        if (p == null) throw new ArgumentNullException(nameof(p));
        p.Neili += 50;
        p.Tili += 100;
        p.NeiliMax = p.Neili;
        p.TiliMax = p.Tili;
        p.Jingyan = 0;
        return p; // 必須回傳修改後的實例 (或新實例)
    }

    public void Show() {
        Console.WriteLine($"Tili: {Tili}/{TiliMax}, Neili: {Neili}/{NeiliMax}, Exp: {Jingyan}");
    }
}

// 使用
var hero = new Player();
hero.Show();
++hero; // 前綴遞增
hero.Show();

注意:operator ++ 應視為回傳新狀態,不建議直接修改傳入參數再回傳 (易造成副作用混淆),較佳做法是建立新實例。

二元運算子多載:3D 向量加法


public struct Vector3D {
    public double X, Y, Z;
    public Vector3D(double x, double y, double z) { X = x; Y = y; Z = z; }

    public static Vector3D operator +(Vector3D left, Vector3D right) =>
        new Vector3D(left.X + right.X, left.Y + right.Y, left.Z + right.Z);

    public static Vector3D operator -(Vector3D left, Vector3D right) =>
        new Vector3D(left.X - right.X, left.Y - right.Y, left.Z - right.Z);

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

// 使用
var v1 = new Vector3D(3, 2, 1);
var v2 = new Vector3D(0, 6, 5);
var v3 = v1 + v2; // (3, 8, 6)
Console.WriteLine(v3);

成對運算子強制規則

運算子組必須成對實作邏輯關係
== / !=是互為邏輯否定
< / >是互為反向比較
<= / >=是互為反向比較
true / false是用於自訂布林轉換 (如 nullable 型別)

若只實作其中一個,編譯器報錯 CS0216。

等號比較完整實作模式


public class Point : IEquatable {
    public int X { get; }
    public int Y { get; }
    public Point(int x, int y) { X = x; Y = y; }

    public static bool operator ==(Point left, Point right) {
        if (ReferenceEquals(left, right)) return true;
        if (ReferenceEquals(left, null) || ReferenceEquals(right, null)) return false;
        return left.Equals(right);
    }
    public static bool operator !=(Point left, Point right) => !(left == right);

    public bool Equals(Point other) => other != null && X == other.X && Y == other.Y;
    public override bool Equals(object obj) => Equals(obj as Point);
    public override int GetHashCode() => HashCode.Combine(X, Y);
}

最佳實務與陷阱

  1. 不可變型別 (struct/readonly class) 最適合運算子多載,回傳新實例。
  2. 避免在運算子中拋出例外 (除非引數驗證),改用 Try 方法模式。
  3. true/false 運算子僅用於支援 if (obj) 語法的特殊型別 (如 DBBool),濫用會造成困惑。
  4. 運算子多載不支援繼承多態:Base b = new Derived(); b + b 呼叫 Base.operator+,非 Derived.operator+。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved