Přetížení operátoru – předdefinované unární, aritmetické, rovnosti a relační operátory
Uživatelem definovaný typ může přetížit předdefinovaný operátor jazyka C#. To znamená, že typ může poskytnout vlastní implementaci operace v případě, že jeden nebo oba operandy jsou tohoto typu. Oddíl Přetížitelné operátory ukazuje, které operátory jazyka C# je možné přetížit.
Pomocí klíčového operator
slova deklarujte operátor. Deklarace operátoru musí splňovat následující pravidla:
- Zahrnuje jak modifikátor,
public
static
tak modifikátor. - Unární operátor má jeden vstupní parametr. Binární operátor má dva vstupní parametry. V každém případě musí mít alespoň jeden parametr typ
T
neboT?
kdeT
je typ, který obsahuje deklaraci operátoru.
Následující příklad definuje zjednodušenou strukturu, která představuje logické číslo. Struktura přetíží některé aritmetické operátory:
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
}
}
Předchozí příklad můžete rozšířit definováním implicitního převodu z int
na Fraction
. Přetížené operátory by pak podporovaly argumenty těchto dvou typů. To znamená, že by bylo možné přidat celé číslo k zlomku a získat zlomek v důsledku toho.
Pomocí klíčového operator
slova můžete také definovat převod vlastního typu. Další informace naleznete v tématu Uživatelem definované operátory převodu.
Přetížitelné operátory
Následující tabulka ukazuje operátory, které je možné přetížit:
Operátory | Notes |
---|---|
+x , -x , !x , , ++ ~x , -- , , true false |
Operátory true a false operátory musí být přetíženy dohromady. |
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 |
Musí být přetíženy ve dvojicích následujícím způsobem: == a != < , a > <= , a >= . |
Nepřetížitelné operátory
Následující tabulka ukazuje operátory, které nelze přetížit:
Operátory | Alternativy |
---|---|
x && y , x || y |
Přetěžujte operátory true i false operátory nebo | operátory& . Další informace naleznete v tématu Uživatelem definované podmíněné logické operátory. |
a[i] , a?[i] |
Definujte indexer. |
(T)x |
Definujte vlastní převody typů, které lze provádět výrazem přetypování. Další informace naleznete v tématu Uživatelem definované operátory převodu. |
+= , -= , , *= , %= <<= /= &= |= ^= , >>= >>>= |
Přetěžte odpovídající binární operátor. Například při přetížení binárního + operátoru += je implicitně přetížen. |
^x , x = y , x.y , , c ? t : f x?.y , x ?? y , , ??= y x..y , x->y , , => , as await , nameof new f(x) checked unchecked default delegate is sizeof , stackalloc , switch , , typeof with |
Nezaokrouhlovat. |
specifikace jazyka C#
Další informace najdete v následujících částech specifikace jazyka C#: