c#入门-重载运算符

所有的运算符重载和类型转换重载都必须是公开,静态方法。
使用关键字operator作为方法名,因为这个位置原本是写方法名的,所以没有代码提示。
重载方法的返回值不一定必须是自己,但一定不能是void。不能在双方类型种定义相同的运算

运算符重载

运算符重载在operator后加上要重载运算符。参数类型至少有一个是自己类型。

一元运算(只有一个参数)

+和-

一元的+-运算一般是数字类型使用的。数字类型使用这些运算表示自己本身和自己的相反数

速度 a = new 速度();
速度 b = +a;
速度 c = -a;
class 速度
{
	public int 米每秒;
	public static 速度 operator +(速度 L) => new 速度 { 米每秒 = L.米每秒 };
	public static 速度 operator -(速度 L) => new 速度 { 米每秒 = -L.米每秒 };
}

~和!

这两个运算符在逻辑运算中和位运算中计算所有比特完全相反的值。

class 速度
{
	public int 米每秒;
	public static bool operator !(速度 L) => L.米每秒 != 0;
	public static int operator ~(速度 L) => -L.米每秒;
}

++和 – –

这两个运算符是数字类型使用的自增和自减。重载的返回值必须是自己或自己的派生。
和数字的自增自减一样,如果写在前面,那么返回计算后的值。
如果写在后面,那么返回还没计算的值。无论哪种方式,计算完毕后的值都会替换原始值。

速度 s = new 速度();
var a = s;
var b = s++;
var c = ++s;
Console.WriteLine(s == a);//False
Console.WriteLine(s == b);//False
Console.WriteLine(a == b);//True
Console.WriteLine(s == c);//True
class 速度
{
	public int 米每秒;
	public static 速度 operator ++(速度 L) => new 速度 { 米每秒 = L.米每秒 + 1 };
	public static 速度 operator --(速度 L) => new 速度 { 米每秒 = L.米每秒 - 1 };
}

true和false

true和false是配对的运算,必须成对重载。且必须返回bool类型。
重载了true后,这个类型可以直接当作流程控制语句和三元运算符的条件。
false重载几乎没什么用。

灵能风暴 a = new 灵能风暴();
if (a) { }
var b = a ? 1 : 2;
//bool c = a;重载true不意味着可以直接转换为bool类型。
//if (!a) { }重载true只能把自己当条件,!a的结果由!运算符重载。
class 灵能风暴
{
	public int 持续时间 { get; protected set; }
	public object[] 影响目标 { get; protected set; }
	public int 每秒伤害 { get; protected set; }
	public static bool operator true(灵能风暴 L) => L is { 持续时间: > 0, 影响目标.Length: > 0 };
	public static bool operator false(灵能风暴 L) => L is not { 持续时间: > 0, 影响目标.Length: > 0 };
}

这两种重载的结果不需要互补。即一方结果为true时,另一方结果可以也是true。

二元运算(有两个参数)

+和 -

计算两个类型相加或相减的结果。
不是所有类型都满足交换律,有些计算必须某种类型在左边。希望两种顺序都能计算就需要重载两个方法。
如果双方都写了相同的定义,那么在进行运算时会无法判断使用哪个类里面的方法。

class 时间段
{
	public int,,;
	public static 时刻 operator +(时间段 L, 时刻 R)
		=> new 时刻() {= L.+ R.,= L.+ R.,= L.+ R.};
}
class 时刻
{
	public int,,;
	public static 时刻 operator +(时刻 L, 时间段 R)
		=> new 时刻() {= L.+ R.,= L.+ R.,= L.+ R.};
	public static 时刻 operator -(时刻 L, 时间段 R)
		=> new 时刻() {= L.- R.,= L.- R.,= L.- R.};
}

*和 / 和%

这个懒得写示例了。

&和 | 和^

这个懒得写示例了。

>>和<<

位运算符。返回类型不限,但左边参数必须是自身类型,右边参数必须是int类型。

>和<

必须成对重载。返回类型必须是bool类型。不需要互补。

>=和<=

必须成对重载。返回类型必须是bool类型。不需要互补。

!=和==

必须成对重载。返回类型必须是bool类型。不需要互补。

自动重载的运算

复合运算

如果二元运算的返回类型是自己,那么对应的复合运算也会一起重载。

速度 a = new 速度();
a += a; 

class 速度
{
	public int 米每秒;
	public static 速度 operator +(速度 L, 速度 R) 
		=> new 速度() { 米每秒 = L.米每秒 + R.米每秒 };
	public static 速度 operator -(速度 L, 速度 R) 
		=> new 速度() { 米每秒 = L.米每秒 - R.米每秒 };
}

逻辑运算

如果重载了&或 | ,且返回类型为自己,且重载了 true 和false。
那么会自动重载&&和 || 。

示例 a = new 示例() { b = false };
示例 b = new 示例() { b = true };
var c = a && b;
var d = a || b;
var e = b && a;
var f = b || a;
Console.WriteLine(a == c); //True
Console.WriteLine(a == d); //False
Console.WriteLine(b == e); //False
Console.WriteLine(b == f); //True
class 示例
{
	public bool b;
	public static 示例 operator &(示例 L, 示例 R) => new 示例();
	public static 示例 operator |(示例 L, 示例 R) => new 示例();
	public static bool operator true(示例 L) => L.b;
	public static bool operator false(示例 L) => !L.b;
}

如果&&左侧值重载的false运算结果为bool值true,那么不会执行&运算直接返回左侧值。
如果 || 左侧值重载的true运算结果为bool值true,那么不会执行 | 运算直接返回左侧值。
否则,计算&或 | 的运算。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值