C# 运算符重载完全指南:自定义类型的运算符行为定义
C# 允许重定义或重载大多数内置运算符,使程序员能将运算符用于用户定义类型。重载运算符是特殊名称的函数:operator 关键字后跟运算符符号。与其他函数一样,有返回类型和参数列表。
运算符重载实现
以 Box 类为例,重载加法运算符 +:
public static Box operator+ (Box b, Box c) {
Box box = new Box();
box.length = b.length + c.length;
box.breadth = b.breadth + c.breadth;
box.height = b.height + c.height;
return box;
}
该函数实现两个 Box 对象相加,返回新的 Box 对象。
完整实现示例
using System;
namespace OperatorOvlApplication {
class Box {
private double length, breadth, height;
public double getVolume() { return length * breadth * height; }
public void setLength(double len) { length = len; }
public void setBreadth(double bre) { breadth = bre; }
public void setHeight(double hei) { height = hei; }
// 重载 + 运算符
public static Box operator+ (Box b, Box c) {
Box box = new Box();
box.length = b.length + c.length;
box.breadth = b.breadth + c.breadth;
box.height = b.height + c.height;
return box;
}
}
class Tester {
static void Main(string[] args) {
Box Box1 = new Box(), Box2 = new Box(), Box3 = new Box();
double volume = 0.0;
Box1.setLength(6.0); Box1.setBreadth(7.0); Box1.setHeight(5.0);
Box2.setLength(12.0); Box2.setBreadth(13.0); Box2.setHeight(10.0);
volume = Box1.getVolume();
Console.WriteLine("Volume of Box1 : {0}", volume); // 210
volume = Box2.getVolume();
Console.WriteLine("Volume of Box2 : {0}", volume); // 1560
// 使用重载的 + 运算符
Box3 = Box1 + Box2;
volume = Box3.getVolume();
Console.WriteLine("Volume of Box3 : {0}", volume); // 5400
Console.ReadKey();
}
}
}
可重载与不可重载运算符
| 类别 | 运算符 | 可重载性 |
|---|---|---|
| 一元运算符 | +, -, !, ~, ++, -- | ✓ 可重载 |
| 二元算术 | +, -, *, /, % | ✓ 可重载 |
| 比较运算符 | ==, !=, <, >, <=, >= | ✓ 可重载(成对重载) |
| 条件逻辑 | &&, || | ✗ 不可直接重载(通过重载 true/false 间接支持) |
| 赋值运算符 | +=, -=, *=, /=, %= | ✗ 不可重载(复合赋值自动对应基础运算符) |
| 其他 | =, ., ?:, ->, new, is, sizeof, typeof | ✗ 不可重载 |
扩展示例:重载比较运算符与 ToString
public static bool operator == (Box lhs, Box rhs) {
return lhs.length == rhs.length && lhs.height == rhs.height && lhs.breadth == rhs.breadth;
}
public static bool operator != (Box lhs, Box rhs) {
return !(lhs == rhs); // 建议复用 == 实现
}
public static bool operator < (Box lhs, Box rhs) {
return lhs.length < rhs.length && lhs.height < rhs.height && lhs.breadth < rhs.breadth;
}
public static bool operator > (Box lhs, Box rhs) {
return lhs.length > rhs.length && lhs.height > rhs.height && lhs.breadth > rhs.breadth;
}
public static bool operator <= (Box lhs, Box rhs) {
return lhs == rhs || lhs < rhs;
}
public static bool operator >= (Box lhs, Box rhs) {
return lhs == rhs || lhs > rhs;
}
public override string ToString() {
return String.Format("({0}, {1}, {2})", length, breadth, height);
}
测试代码
Box Box1 = new Box(); Box1.setLength(6); Box1.setBreadth(7); Box1.setHeight(5);
Box Box2 = new Box(); Box2.setLength(12); Box2.setBreadth(13); Box2.setHeight(10);
Box Box3 = Box1 + Box2;
Box Box4 = Box3;
Console.WriteLine("Box 1: {0}", Box1); // (6, 7, 5)
Console.WriteLine("Box 2: {0}", Box2); // (12, 13, 10)
Console.WriteLine("Box 3: {0}", Box3); // (18, 20, 15)
Console.WriteLine(Box1 > Box2 ? "Box1 > Box2" : "Box1 <= Box2"); // Box1 <= Box2
Console.WriteLine(Box1 < Box2 ? "Box1 < Box2" : "Box1 >= Box2"); // Box1 < Box2
Console.WriteLine(Box3 == Box4 ? "Box3 == Box4" : "Box3 != Box4"); // Box3 == Box4
重载规则与最佳实践
- 重载运算符必须声明为
public static - 一元运算符一个参数,二元运算符两个参数(至少一个为包含类型)
- 比较运算符必须成对重载(== 与 !=、< 与 >、<= 与 >=)
- 重载
==时应重写Equals()和GetHashCode() - 避免重载运算符产生非直观行为(如
+做减法) - 结构体重载运算符需注意值类型拷贝语义
C语言
- 操作员参与维护:收益是否大于隐性成本?
- DIY仿Wall-E树莓派CD盒机器人
- C#运算符——C#运算符全面指南
- C# 三元运算符:条件表达式简明指南
- 掌握 C# 方法重载:核心概念、实战示例与最佳实践
- 掌握 C# 构造函数重载:灵活创建对象的多种姿势
- C++ 运算符重载实战指南:语法、方法、限制与代码示例
- C++重载机制深度解析:函数重载与运算符重载全攻略
- C# 类完全指南:定义、封装、构造函数、析构函数与静态成员
- MATLAB 基础语法速成:交互计算、变量、运算符、格式控制与注释
- 精通 Python 运算符重载:实战指南
- Java instanceof 运算符完全指南:用法、继承与接口检查