Przeciążanie operatorów — wstępnie zdefiniowane jednoargumentowe, arytmetyczne, równości i operatory porównania
Typ zdefiniowany przez użytkownika może przeciążać wstępnie zdefiniowany operator języka C#. Oznacza to, że typ może zapewnić niestandardową implementację operacji w przypadku, gdy jeden lub oba operandy są tego typu. Sekcja Przeciążenia operatorów pokazuje, które operatory języka C# mogą być przeciążone.
Użyj słowa kluczowego operator
, aby zadeklarować operator. Deklaracja operatora musi spełniać następujące reguły:
- Zawiera zarówno modyfikator, jak
public
static
i . - Operator jednoargumentowy ma jeden parametr wejściowy. Operator binarny ma dwa parametry wejściowe. W każdym przypadku co najmniej jeden parametr musi mieć typ
T
lubT?
gdzieT
jest typem zawierającym deklarację operatora.
W poniższym przykładzie zdefiniowano uproszczoną strukturę reprezentującą liczbę racjonalną. Struktura przeciąża niektóre operatory arytmetyczne:
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
}
}
Powyższy przykład można rozszerzyć, definiując niejawną konwersję z int
na Fraction
. Następnie przeciążone operatory obsługują argumenty tych dwóch typów. Oznacza to, że możliwe byłoby dodanie liczby całkowitej do ułamka i uzyskanie ułamka w wyniku.
Słowo kluczowe służy operator
również do definiowania konwersji typu niestandardowego. Aby uzyskać więcej informacji, zobacz Operatory konwersji zdefiniowane przez użytkownika.
Operatory przeciążalne
W poniższej tabeli przedstawiono operatory, które mogą być przeciążone:
Operatory | Uwagi |
---|---|
+x , -x , , !x , ++ ~x , , -- , , true false |
Operatory true i false muszą być ze sobą przeciążone. |
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 |
Muszą być przeciążone w parach w następujący sposób: == i != , < i > .>= <= |
Nie przeciążalne operatory
W poniższej tabeli przedstawiono operatory, których nie można przeciążyć:
Operatory | Alternatywy |
---|---|
x && y , x || y |
Przeciąż operatory true i oraz false & operatory lub | . Aby uzyskać więcej informacji, zobacz Operatory logiczne warunkowe zdefiniowane przez użytkownika. |
a[i] , a?[i] |
Zdefiniuj indeksator. |
(T)x |
Zdefiniuj konwersje typów niestandardowych, które mogą być wykonywane przez wyrażenie rzutowane. Aby uzyskać więcej informacji, zobacz Operatory konwersji zdefiniowane przez użytkownika. |
+= , -= , , , %= ^= >>= /= &= |= <<= *= >>>= |
Przeciąż odpowiedniego operatora binarnego. Na przykład podczas przeciążenia operatora += binarnego + jest niejawnie przeciążony. |
^x , x = y , , x.y , c ? t : f x?.y , , x ?? y , , ??= y x..y , x->y , , , as await nameof f(x) unchecked new checked default delegate is => sizeof , , stackalloc , switch , , typeof with |
Brak. |
specyfikacja języka C#
Aby uzyskać więcej informacji, zobacz następujące sekcje specyfikacji języka C#: