# 运算符重载
概念：
- 运算符重载可以让==自定义类型==像内置类型一样使用某些运算符
- 本质上是给运算符提供一套你自己定义的行为

通常用法：
- 坐标、向量、复数、金额等“天然适合运算”的类型

语法：
```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` 和 `&` / `|` 实现相关行为

#核心
