C# 运算符重载(operator overloading) - 自定义类型的算术运算

来源:这里教程网 时间:2026-02-21 17:40:49 作者:

在 C# 中,运算符重载允许你为自定义类型(如结构体或类)定义 +-*/== 等运算符的行为,让它们像内置类型一样自然参与算术或比较运算。

哪些运算符可以重载

不是所有运算符都能重载。C# 支持重载的包括:

一元运算符:+-!~++--truefalse 二元运算符:+-*/%&|^>>==!=>>= 必须成对重载的比较运算符:==!=,或 > 等(否则编译报错)

基本语法和规则

运算符重载必须用 public static 修饰,且至少一个参数是当前类型。不能改变运算符的优先级、结合性或操作数个数。

例如,为表示二维坐标的 Point 结构重载加法:

public struct Point
{
    public int X { get; }
    public int Y { get; }
<pre class="brush:php;toolbar:false;">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# 的表达习惯。

相关推荐