83 lines
1.8 KiB
Markdown
83 lines
1.8 KiB
Markdown
# 运算符重载
|
|
概念:
|
|
- 运算符重载可以让==自定义类型==像内置类型一样使用某些运算符
|
|
- 本质上是给运算符提供一套你自己定义的行为
|
|
|
|
通常用法:
|
|
- 坐标、向量、复数、金额等“天然适合运算”的类型
|
|
|
|
语法:
|
|
```csharp
|
|
public static 返回值类型 operator 运算符(参数列表)
|
|
{
|
|
// 自定义逻辑
|
|
}
|
|
```
|
|
|
|
案例:
|
|
```csharp
|
|
class Point
|
|
{
|
|
public int X;
|
|
public int Y;
|
|
|
|
public static Point operator +(Point p1, Point p2)
|
|
{
|
|
return new Point
|
|
{
|
|
X = p1.X + p2.X,
|
|
Y = p1.Y + p2.Y
|
|
};
|
|
}
|
|
|
|
public static Point operator +(Point p, int value)
|
|
{
|
|
return new Point
|
|
{
|
|
X = p.X + value,
|
|
Y = p.Y + value
|
|
};
|
|
}
|
|
}
|
|
|
|
Point p1 = new Point { X = 1, Y = 1 };
|
|
Point p2 = new Point { X = 2, Y = 2 };
|
|
|
|
Point p3 = p1 + p2;
|
|
Point p4 = p1 + 10;
|
|
Console.WriteLine($"{p3.X}, {p3.Y}");
|
|
Console.WriteLine($"{p4.X}, {p4.Y}");
|
|
```
|
|
|
|
补充:
|
|
- 如果你希望 `10 + p1` 也成立,需要再额外写一份对应重载
|
|
- 运算符重载最重要的是==语义自然==,不要让 `+` 去做奇怪的事
|
|
|
|
常见可重载运算符:
|
|
- 一元:`+` `-` `!` `~` `++` `--` `true` `false`
|
|
- 二元:`+` `-` `*` `/` `%` `&` `|` `^` `<<` `>>`
|
|
- 比较:`==` `!=` `<` `>` `<=` `>=`
|
|
|
|
不能直接重载的常见运算符:
|
|
- `&&` `||`
|
|
- `[]`
|
|
- `()`
|
|
- `.`
|
|
- `=`
|
|
- `?:`
|
|
- `??`
|
|
|
|
注意:
|
|
1. ==传统写法里,运算符重载通常写成 `public static`==
|
|
2. 参数里至少要有一个参数是当前类型
|
|
3. 不能给运算符参数加 `ref` 或 `out`
|
|
4. 某些运算符需要成对实现:
|
|
- `==` 和 `!=`
|
|
- `<` 和 `>`
|
|
- `<=` 和 `>=`
|
|
- `true` 和 `false`
|
|
5. 如果重载了 `==` / `!=`,通常也应该一起重写 `Equals` 和 `GetHashCode`
|
|
6. `&&` / `||` 不能直接重载,但可以结合 `true` / `false` 和 `&` / `|` 实现相关行为
|
|
|
|
#核心
|