Przeciążanie operatora (C# odwołanie)Operator overloading (C# reference)

Typ zdefiniowany przez użytkownika może przeciążać wstępnie C# zdefiniowany operator.A user-defined type can overload a predefined C# operator. Oznacza to, że typ może zapewnić niestandardową implementację operacji w przypadku, gdy jeden lub oba operandy są tego typu.That is, a type can provide the custom implementation of an operation in case one or both of the operands are of that type. Sekcja Operatory z możliwością przeciążenia pokazuje, C# które operatory mogą być przeciążone.The Overloadable operators section shows which C# operators can be overloaded.

Użyj słowa kluczowego operator, aby zadeklarować operator.Use the operator keyword to declare an operator. Deklaracja operatora musi spełniać następujące zasady:An operator declaration must satisfy the following rules:

  • Zawiera zarówno modyfikator public, jak i static.It includes both a public and a static modifier.
  • Jednoargumentowy operator ma jeden parametr wejściowy.A unary operator has one input parameter. Operator binarny ma dwa parametry wejściowe.A binary operator has two input parameters. W każdym przypadku co najmniej jeden parametr musi mieć typ T lub T?, gdzie T jest typem, który zawiera deklarację operatora.In each case, at least one parameter must have type T or T? where T is the type that contains the operator declaration.

Poniższy przykład definiuje uproszczoną strukturę do reprezentowania liczby wymiernej.The following example defines a simplified structure to represent a rational number. Struktura przeciąża niektóre Operatory arytmetyczne: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
    }
}

Możesz poszerzyć poprzedni przykład, definiując niejawną konwersję z int na Fraction.You could extend the preceding example by defining an implicit conversion from int to Fraction. Następnie przeciążone operatory obsługują argumenty tych dwóch typów.Then, overloaded operators would support arguments of those two types. Oznacza to, że można dodać liczbę całkowitą do ułamka i uzyskać ułamek jako wynik.That is, it would become possible to add an integer to a fraction and obtain a fraction as a result.

Możesz również użyć słowa kluczowego operator, aby zdefiniować niestandardową konwersję typu.You also use the operator keyword to define a custom type conversion. Aby uzyskać więcej informacji, zobacz Operatory konwersji zdefiniowane przez użytkownika.For more information, see User-defined conversion operators.

Operatory z możliwością przeciążeniaOverloadable operators

Poniższa tabela zawiera informacje dotyczące przeciążania C# operatorów:The following table provides information about overloadability of C# operators:

OperatoryOperators PrzeciążenieOverloadability
+ x, -x, ! x, ~ x, ++, --, true, false+x, -x, !x, ~x, ++, --, true, false Te operatory jednoargumentowe mogą być przeciążone.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 Te operatory binarne mogą być przeciążone.These binary operators can be overloaded. Niektóre operatory muszą być przeciążone w parach; Więcej informacji można znaleźć w poniższej tabeli.Certain operators must be overloaded in pairs; for more information, see the note that follows this table.
x & & y, x | | yx && y, x || y Warunkowe operatory logiczne nie mogą być przeciążone.Conditional logical operators cannot be overloaded. Jednakże, jeśli typ z przeciążonymi true i operatory false również przeciąża operator & lub | w określony sposób, można obliczyć odpowiednio operatora && lub ||, które są odpowiednie dla operandów tego typu.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. Aby uzyskać więcej informacji, zapoznaj się z sekcją Operatory logiczne warunkowe w C# specyfikacji języka.For more information, see the User-defined conditional logical operators section of the C# language specification.
a[i]a[i] Dostęp do elementu nie jest traktowany jako operator z możliwością przeciążenia, ale można zdefiniować indeksator.Element access is not considered an overloadable operator, but you can define an indexer.
(T) x(T)x Operator rzutowania nie może być przeciążony, ale można zdefiniować nowe operatory konwersji.The cast operator cannot be overloaded, but you can define new conversion operators. Aby uzyskać więcej informacji, zobacz Operatory konwersji zdefiniowane przez użytkownika.For more information, see User-defined conversion operators.
+=, -=, *=, /=, %=, &=, |=, ^=, <<,=t_22_+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>= Operatory przypisania złożonego nie mogą być jawnie przeciążone.Compound assignment operators cannot be explicitly overloaded. Jednak w przypadku przeciążenia operatora binarnego odpowiedni operator przypisania złożonego, jeśli istnieje, również jest niejawnie przeciążony.However, when you overload a binary operator, the corresponding compound assignment operator, if any, is also implicitly overloaded. Na przykład += jest oceniane przy użyciu +, który może być przeciążony.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, niezaznaczone, niezaznaczone, Domyślnie, Delegat, 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 Te operatory nie mogą być przeciążone.These operators cannot be overloaded.

Uwaga

Operatory porównania muszą być przeciążone w parach.The comparison operators must be overloaded in pairs. Oznacza to, że jeśli oba operatory pary są przeciążone, drugi operator musi być przeciążony.That is, if either operator of a pair is overloaded, the other operator must be overloaded as well. Takie pary są następujące:Such pairs are as follows:

  • Operatory == i !=== and != operators
  • Operatory < i >< and > operators
  • Operatory <= i >=<= and >= operators

specyfikacja języka C#C# language specification

Aby uzyskać więcej informacji, zobacz następujące sekcje C# specyfikacji języka:For more information, see the following sections of the C# language specification:

Zobacz takżeSee also