C#中可重载运算符包括一元(+、-、!、~、++、--、true、false)、二元(+、-、*、/、%、&、|、^、、==、!=、、=)及必须成对重载的比较运算符;重载需用public static修饰,至少一个参数为当前类型,且不可改变优先级、结合性或操作数个数。

在 C# 中,运算符重载允许你为自定义类型(如结构体或类)定义 +、-、*、/、== 等运算符的行为,让它们像内置类型一样自然参与算术或比较运算。
哪些运算符可以重载
不是所有运算符都能重载。C# 支持重载的包括:
- 一元运算符:+、-、!、~、++、--、true、false
- 二元运算符:+、-、*、/、%、&、|、^、、>>、==、!=、、>、、>=
- 必须成对重载的比较运算符:== 和 !=,或 和 > 等(否则编译报错)
基本语法和规则
运算符重载必须用 public static 修饰,且至少一个参数是当前类型。不能改变运算符的优先级、结合性或操作数个数。
例如,为表示二维坐标的 Point 结构重载加法:
public struct Point
{
public int X { get; }
public int Y { get; }
public Point(int x, int y) => (X, Y) = (x, y);
public static Point operator +(Point a, Point b) =>
new Point(a.X + b.X, a.Y + b.Y);}
之后就能直接写:var p3 = p1 + p2;
重载相等运算符(== 和 !=)的注意事项
如果重载了 == 和 !=,强烈建议同时重写 Equals(object)、GetHashCode(),并实现 IEquatable 接口,否则可能引发不一致行为(比如字典查找失败、HashSet 重复添加)。
典型写法:
- 先判断是否为 null(引用类型)或使用 ReferenceEquals(避免递归)
- 用成员逐项比较,避免装箱(值类型慎用 object.Equals)
- GetHashCode 必须与 Equals 逻辑一致:相等的对象必须返回相同哈希码
常见陷阱与建议
运算符重载不是语法糖,而是语义契约——它应该符合直觉。比如 + 应该是无副作用、可交换的;== 应该是自反、对称、传递的。
- 避免重载让代码难以理解,比如用 + 触发网络请求
- 结构体尽量用 readonly struct 配合运算符重载,保证不可变性
- 不要重载 && 或 ||(短路逻辑),C# 不支持;可用 & 和 | 替代(但语义不同)
- 用户定义的转换运算符(implicit/explicit)可配合运算符提升表达力,但要谨慎防止隐式转换引发歧义
基本上就这些。合理使用运算符重载能让自定义类型更自然、更安全地融入 C# 的表达习惯。










