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. Část 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átora musí splňovat následující pravidla:

  • Obsahuje modifikátor i publicstatic 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 nebo T? kde T je typ, který obsahuje deklaraci operátoru.

Následující příklad definuje zjednodušenou strukturu, která představuje racionální číslo. Struktura přetíží některé z aritmetických operátorů:

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 pak podporují argumenty těchto dvou typů. To znamená, že by bylo možné přidat celé číslo k zlomku a získat zlomek jako výsledek.

Klíčové slovo také použijete operator k definování převodu vlastního typu. Další informace najdete v tématu Uživatelem definované převodní operátory.

Přetížitelné operátory

Následující tabulka uvádí operátory, které je možné přetížit:

Operátory Poznámky
+x, -x, !x, ~x, ++, --, true, false Operátory true a false musí být společně přetíženy.
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 uvádí operátory, které nelze přetížit:

Operátory Alternativy
x && y, x || y Přetěžte operátory true a false operátory & nebo | . Další informace najdete 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 pomocí výrazu přetypování. Další informace najdete v tématu Uživatelem definované převodní operátory.
+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=, >>>= 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, 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
Žádné

specifikace jazyka C#

Další informace najdete v následujících částech specifikace jazyka C#:

Viz také