Operatorüberladung (C#-Referenz)Operator overloading (C# reference)

Ein benutzerdefinierter Typ kann einen vordefinierten C#-Operator überladen.A user-defined type can overload a predefined C# operator. Das bedeutet, dass ein Typ die benutzerdefinierte Implementierung eines Vorgangs bereitstellen kann, wenn mindestens einer der beiden Operanden vom selben Typ ist.That is, a type can provide the custom implementation of an operation in case one or both of the operands are of that type. Im Abschnitt Überladbare Operatoren werden die C#-Operatoren angegeben, die überladen werden können.The Overloadable operators section shows which C# operators can be overloaded.

Verwenden Sie das Schlüsselwort operator, um einen Operator zu deklarieren.Use the operator keyword to declare an operator. Jede Operatordeklaration muss mit den folgenden Regeln konform sein:An operator declaration must satisfy the following rules:

  • Sie enthält sowohl einen public- als auch einen static-Modifizierer.It includes both a public and a static modifier.
  • Ein unärer Operator verfügt über einen Eingabeparameter.A unary operator has one input parameter. Ein binärer Operator verfügt über zwei Eingabeparameter.A binary operator has two input parameters. Auf jeden Fall muss mindestens ein Parameter vom Typ T oder T? sein, wobei T der Typ ist, der die Operatordeklaration enthält.In each case, at least one parameter must have type T or T? where T is the type that contains the operator declaration.

Das folgende Beispiel definiert eine vereinfachte Struktur für die Darstellung einer rationalen Zahl.The following example defines a simplified structure to represent a rational number. Die Struktur überlädt einige der arithmetischen Operatoren:The structure overloads some of the arithmetic operators:

using System;

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
    }
}

Sie könnten das vorherige Beispiel erweitern, indem Sie eine implizite Konvertierung von int nach Fraction definieren.You could extend the preceding example by defining an implicit conversion from int to Fraction. Dann würden überladene Operatoren Argumente dieser beiden Typen unterstützen.Then, overloaded operators would support arguments of those two types. Das bedeutet, dass es dann möglich wäre, eine ganze Zahl und einen Bruch zu addieren und als Ergebnis einen Bruch zu erhalten.That is, it would become possible to add an integer to a fraction and obtain a fraction as a result.

Verwenden Sie zudem das Kennwort operator, um eine benutzerdefinierte Konvertierung zu definieren.You also use the operator keyword to define a custom type conversion. Weitere Informationen finden Sie unter Benutzerdefinierte Konvertierungsoperatoren.For more information, see User-defined conversion operators.

Überladbare OperatorenOverloadable operators

Die folgende Tabelle enthält Informationen zur Überladbarkeit von C#-Operatoren:The following table provides information about overloadability of C# operators:

OperatorenOperators ÜberladbarkeitOverloadability
+x, -x, !x, ~x, ++, --, true, false+x, -x, !x, ~x, ++, --, true, false Diese unären Operatoren können überladen werden.These unary operators can be overloaded.
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 >= yx + 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 Diese binären Operatoren können überladen werden.These binary operators can be overloaded. Manche Operatoren müssen paarweise überladen werden. Weitere Informationen dazu finden Sie im Hinweisfeld unter dieser Tabelle.Certain operators must be overloaded in pairs; for more information, see the note that follows this table.
x && y, x || yx && y, x || y Bedingte logische Operatoren können nicht überladen werden.Conditional logical operators cannot be overloaded. Wenn jedoch ein Typ mit den überladenen Operatoren true und false ebenfalls den Operator& oder | auf eine bestimmte Weise überlädt, kann jeweils entweder der Operator && oder der Operator || für die Operanden dieses Typs ausgewertet werden.However, if a type with the overloaded true and false operators also overloads the & or | operator in a certain way, the && or || operator, respectively, can be evaluated for the operands of that type. Weitere Informationen finden Sie im Abschnitt Benutzerdefinierte bedingte logische Operatoren der C#-Sprachspezifikation.For more information, see the User-defined conditional logical operators section of the C# language specification.
a[i]a[i] Der Elementzugriff wird nicht als überladbarer Operator betrachtet. Sie können aber einen Indexer definieren.Element access is not considered an overloadable operator, but you can define an indexer.
(T)x(T)x Der Umwandlungsoperator kann nicht überladen werden. Sie können jedoch neue Konvertierungsoperatoren definieren.The cast operator cannot be overloaded, but you can define new conversion operators. Weitere Informationen finden Sie unter Benutzerdefinierte Konvertierungsoperatoren.For more information, see User-defined conversion operators.
+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>= Zusammengesetzte Zuweisungsoperatoren können nicht explizit überladen werden.Compound assignment operators cannot be explicitly overloaded. Wenn Sie einen binären Operator überladen, wird der zugehörige zusammengesetzte Zuweisungsoperator jedoch, sofern er vorhanden ist, auch implizit überladen.However, when you overload a binary operator, the corresponding compound assignment operator, if any, is also implicitly overloaded. Wenn += beispielsweise mit + ausgewertet wird. Selbiger kann überladen werden.For example, += is evaluated using +, which can be overloaded.
^x, x = y, x.y, c ? t : f, x ?? y, x ??= y, x..y, x->y, =>, f(x), as, await, checked, unchecked, default, delegate, is, nameof, new, sizeof, stackalloc, typeof^x, x = y, x.y, c ? t : f, x ?? y, x ??= y, x..y, x->y, =>, f(x), as, await, checked, unchecked, default, delegate, is, nameof, new, sizeof, stackalloc, typeof Diese Operatoren können nicht überladen werden.These operators cannot be overloaded.

Hinweis

Die Vergleichsoperatoren müssen paarweise überladen werden.The comparison operators must be overloaded in pairs. Das bedeutet: Wenn ein Operator überladen wird, der einem Paar angehört, muss der andere Operator ebenfalls überladen werden.That is, if either operator of a pair is overloaded, the other operator must be overloaded as well. Dies kann für die folgenden Paare zutreffen:Such pairs are as follows:

  • Die Operatoren == und !=== and != operators
  • Die Operatoren < und >< and > operators
  • Die Operatoren <= und >=<= and >= operators

C#-SprachspezifikationC# language specification

Weitere Informationen finden Sie in den folgenden Abschnitten der C#-Sprachspezifikation:For more information, see the following sections of the C# language specification:

Siehe auchSee also