Operator overbelasten - vooraf gedefinieerde unaire, rekenkundige, gelijkheids- en vergelijkingsoperatoren

Een door de gebruiker gedefinieerd type kan een vooraf gedefinieerde C#-operator overbelasten. Dat wil gezegd, een type kan de aangepaste implementatie van een bewerking bieden voor het geval een of beide operanden van dat type zijn. In de sectie Overbelastingsbare operators ziet u welke C#-operators kunnen worden overbelast.

Gebruik het operator trefwoord om een operator te declareren. Een operatordeclaratie moet voldoen aan de volgende regels:

  • Het bevat zowel een public als een static modifier.
  • Een unaire operator heeft één invoerparameter. Een binaire operator heeft twee invoerparameters. In elk geval moet ten minste één parameter een type T hebben of T? waar T het type is dat de operatordeclaratie bevat.

In het volgende voorbeeld wordt een vereenvoudigde structuur gedefinieerd die een rationeel getal vertegenwoordigt. De structuur overbelast enkele rekenkundige operatoren:

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

U kunt het voorgaande voorbeeld uitbreiden door een impliciete conversie van int naar .Fraction Vervolgens ondersteunen overbelaste operators argumenten van deze twee typen. Dat wil gezegd, het zou mogelijk zijn om een geheel getal toe te voegen aan een breuk en een breuk te verkrijgen als gevolg hiervan.

U gebruikt ook het operator trefwoord om een conversie van aangepaste typen te definiëren. Zie Door de gebruiker gedefinieerde conversieoperators voor meer informatie.

Overbelastingsoperators

In de volgende tabel ziet u de operators die kunnen worden overbelast:

Operators Opmerkingen
+x, , -x!x, ~x, , ++, , --truefalse De true operatoren moeten false samen overbelast zijn.
x + y, , x - yx * y, x / y, , , x % y
x & y, , , x | yx ^ y
x << y, , x >> yx >>> y
x == y, , x != yx < y, x > y, , , x <= yx >= y Moet als volgt in paren worden overbelast: == en !=, < en >, <= en >=.

Niet-overbelaste operators

In de volgende tabel ziet u de operators die niet kunnen worden overbelast:

Operators Alternatieven
x && y, x || y Zowel de true operatoren als de operatoren en false de & operatoren | overbelasten. Zie Door de gebruiker gedefinieerde logische operators voor meer informatie.
a[i], a?[i] Definieer een indexeerfunctie.
(T)x Definieer aangepaste typeconversies die kunnen worden uitgevoerd door een cast-expressie. Zie Door de gebruiker gedefinieerde conversieoperators voor meer informatie.
+=, , -=*=, /=, %=, , &=, , <<=^=>>=|=>>>= De bijbehorende binaire operator overbelasten. Als u bijvoorbeeld de binaire + operator overbelast, += wordt impliciet overbelast.
^x, , x = yx.y, x?.y, , c ? t : f, , x ?? y??= y
x..y, , =>x->y, f(x), , as, , awaitchecked, unchecked, delegatedefaultisnameofnew,
sizeofswitch, stackalloc, typeofwith
Geen.

C#-taalspecificatie

Zie de volgende secties van de C#-taalspecificatie voor meer informatie:

Zie ook