运算符重载 - 预定义的一元运算符、算术运算符、相等运算符和比较运算符
用户定义的类型可重载预定义的 C# 运算符。 也就是说,当一个或两个操作数都是某类型时,此类型可提供操作的自定义实现。 可重载运算符部分介绍了哪些 C# 运算符可重载。
使用 operator
关键字来声明运算符。 运算符声明必须符合以下规则:
- 同时包含
public
和static
修饰符。 - 一元运算符有一个输入参数。 二元运算符有两个输入参数。 在每种情况下,都至少有一个参数必须具有类型
T
或T?
,其中T
是包含运算符声明的类型。
下面的示例定义了一个表示有理数的简单结构。 该结构会重载一些算术运算符:
public readonly struct Fraction
{
private readonly int num;
private readonly int den;
public Fraction(int numerator, int denominator)
{
if (denominator == 0)
{
throw new ArgumentException("Denominator cannot be zero.", nameof(denominator));
}
num = numerator;
den = denominator;
}
public static Fraction operator +(Fraction a) => a;
public static Fraction operator -(Fraction a) => new Fraction(-a.num, a.den);
public static Fraction operator +(Fraction a, Fraction b)
=> new Fraction(a.num * b.den + b.num * a.den, a.den * b.den);
public static Fraction operator -(Fraction a, Fraction b)
=> a + (-b);
public static Fraction operator *(Fraction a, Fraction b)
=> new Fraction(a.num * b.num, a.den * b.den);
public static Fraction operator /(Fraction a, Fraction b)
{
if (b.num == 0)
{
throw new DivideByZeroException();
}
return new Fraction(a.num * b.den, a.den * b.num);
}
public override string ToString() => $"{num} / {den}";
}
public static class OperatorOverloading
{
public static void Main()
{
var a = new Fraction(5, 4);
var b = new Fraction(1, 2);
Console.WriteLine(-a); // output: -5 / 4
Console.WriteLine(a + b); // output: 14 / 8
Console.WriteLine(a - b); // output: 6 / 8
Console.WriteLine(a * b); // output: 5 / 8
Console.WriteLine(a / b); // output: 10 / 4
}
}
可以通过定义从 int
到 Fraction
的隐式转换来扩展前面的示例。 然后,重载运算符将支持这两种类型的参数。 也就是说,可以将一个整数添加到一个分数中,得到一个分数结果。
还可以使用 operator
关键字来定义自定义类型转换。 有关详细信息,请参阅用户定义转换运算符。
可重载运算符
下表显示了可以重载的运算符:
运算符 | 说明 |
---|---|
+x , -x , !x , ~x , ++ , -- , true , false |
true 和 false 运算符必须一起重载。 |
x + y , x - y , x * y , x / y , x % y ,x & y , x | y , x ^ y ,x << y , x >> y , x >>> y |
|
x == y , x != y , x < y , x > y , x <= y , x >= y |
必须按如下方式成对重载: == 和 != 、 < 、 > <= 和 >= 。 |
不可重载运算符
下表显示了无法重载的运算符:
运算符 | 备选方法 |
---|---|
x && y , x || y |
重载 true 和 false 运算符以及 & 或 | 运算符。 有关详细信息,请参阅用户定义的条件逻辑运算符。 |
a[i] , a?[i] |
定义索引器。 |
(T)x |
定义可由强制转换表达式执行的自定义类型转换。 有关详细信息,请参阅用户定义转换运算符。 |
+= , -= , *= , /= , %= , &= , |= , ^= , <<= , >>= , >>>= |
重载相应的二元运算符。 例如,重载二元 + 运算符时, += 将隐式重载。 |
^x , x = y , x.y , x?.y , c ? t : f , x ?? y , ??= y ,x..y , x->y , => , f(x) , as , await , checked , unchecked , default , delegate , is , nameof , new ,sizeof , stackalloc , switch , typeof , with |
无。 |
C# 语言规范
有关更多信息,请参阅 C# 语言规范的以下部分: