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

C# 運算子多載完整指南:成對出現、靜態方法與 Equals/GetHashCode 實作

     編輯:關於C語言

前言

C# 允許多載運算子,但規則比 C++ 嚴格:必須為 static、至少一個參數為宣告類別型別、比較運算子必須成對實作、且必須覆寫 Equals 與 GetHashCode。本文詳細說明規則與完整範例。

運算子多載規則速查

類別運算子成對要求
比較==, !=是
關係<, >, <=, >=是
邏輯true, false是
算術+, -, *, /, %否
一元++, --, !, ~否

此外,多載 == 時編譯器會強制要求覆寫 Equals(object) 與 GetHashCode(),確保集合行為一致。

完整範例:姓名比較類別

public class Namer
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public Namer() : this(null, null) { }
    public Namer(string fn, string ln) { FirstName = fn; LastName = ln; }

    // 1. true/false 運算子:判斷姓名是否完整
    public static bool operator true(Namer n)
        => n?.FirstName != null && n.LastName != null;

    public static bool operator false(Namer n)
        => n?.FirstName == null || n.LastName == null;

    // 2. 相等/不相等
    public static bool operator ==(Namer n1, Namer n2)
    {
        if (ReferenceEquals(n1, n2)) return true;
        if (n1 is null || n2 is null) return false;
        return n1.FirstName == n2.FirstName && n1.LastName == n2.LastName;
    }

    public static bool operator !=(Namer n1, Namer n2)
        => !(n1 == n2);

    // 3. 大小比較 (依姓氏再名字字典序)
    public static bool operator >(Namer n1, Namer n2)
    {
        if (n1 is null || n2 is null) return false;
        int cmp = string.Compare(n1.LastName, n2.LastName, StringComparison.Ordinal);
        return cmp > 0 || (cmp == 0 && string.Compare(n1.FirstName, n2.FirstName, StringComparison.Ordinal) > 0);
    }

    public static bool operator <(Namer n1, Namer n2)
        => n2 > n1;

    // 4. 必須覆寫
    public override bool Equals(object obj)
        => obj is Namer other && this == other;

    public override int GetHashCode()
        => (FirstName, LastName).GetHashCode();

    public override string ToString()
        => $"姓:{FirstName} 名:{LastName}";
}

測試程式碼

static void Main()
{
    var n1 = new Namer("Li", "Zanhong");
    var n2 = new Namer("Ahang", "Aan");

    Console.WriteLine(n1 == n2 ? "同名" : "不同名"); // 不同名
    Console.WriteLine(n1 != n2 ? "不等成立" : "相等成立"); // 不等成立
    Console.WriteLine(n1 > n2 ? $"{n1} > {n2}" : n1 < n2 ? $"{n1} < {n2}" : "無法比較");
    // 輸出: 姓:Li 名:Zanhong > 姓:Ahang 名:Aan

    // 測試 true/false 運算子 (用於 if 條件)
    Namer incomplete = new Namer("OnlyFirst", null);
    if (incomplete) Console.WriteLine("完整"); else Console.WriteLine("不完整"); // 不完整
}

常見錯誤與最佳實務

  • 忘記成對:只寫 == 不寫 != → 編譯錯誤 CS0216。
  • Equals/GetHashCode 不一致:導致 Dictionary、HashSet 行為異常。GetHashCode 應基於參與比較的欄位計算。
  • 參考相等處理:== 實作中先檢查 ReferenceEquals 與 null,避免無限遞迴。
  • 不可變型別:多載運算子的類別最好設計為不可變,確保雜湊碼穩定。

結語

掌握 C# 運算子多載的嚴格規則,能讓自訂型別像內建型別一樣自然參與運算與比較,提升程式碼可讀性與型別安全性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved