Overload degli operatori : operatori unari, aritmetici, di uguaglianza e di confronto predefiniti
Un tipo definito dall'utente può eseguire l'overload di un operatore C# definito in precedenza. In altri termini, un tipo può fornire l'implementazione personalizzata di un'operazione quando uno o entrambi gli operandi sono di quel tipo. La sezione Operatori che supportano l'overload illustra gli operatori C# che possono essere sottoposti a overload.
Per dichiarare un operatore, usare la parola chiave operator
. Una dichiarazione di operatore deve soddisfare le regole seguenti:
- Include sia un modificatore
public
che un modificatorestatic
. - Un operatore unario ha un parametro di input. Un operatore binario ha due parametri di input. In entrambi i casi almeno un parametro deve essere di tipo
T
oT?
, doveT
è il tipo che contiene la dichiarazione dell'operatore.
L'esempio seguente definisce una struttura semplificata per la rappresentazione di un numero razionale. La struttura esegue l'overload di alcuni operatori aritmetici:
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
}
}
È possibile estendere l'esempio precedente definendo una conversione implicita da int
in Fraction
. Gli operatori di overload supporteranno quindi gli argomenti di questi due tipi. Diventerà quindi possibile aggiungere un numero intero a una frazione e ottenere di conseguenza una frazione.
È anche possibile usare la parola chiave operator
per definire una conversione del tipo personalizzata. Per altre informazioni, vedere Operatori di conversione definiti dall'utente.
Operatori che supportano l'overload
La tabella seguente mostra gli operatori che possono essere sottoposti a overload:
Operatori | Note |
---|---|
+x , -x , !x , ~x , ++ , -- , true , false |
Gli operatori true e false devono essere sottoposti a overload insieme. |
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 |
Deve essere sottoposto a overload in coppie come indicato di seguito: == e != , < e > , <= e >= . |
Operatori che non supportano l’overload
La tabella seguente illustra gli operatori che non possono essere sottoposti a overload:
Operatori | Alternative |
---|---|
x && y , x || y |
Eseguire l'overload sia degli operatori true chee false e sia degli operatori & o | . Per ulteriori informazioni, consultare Operatori logici condizionali definiti dall'utente. |
a[i] , a?[i] |
Definire un indicizzatore. |
(T)x |
Definire conversioni di tipi personalizzate che possono essere eseguite da un'espressione cast. Per altre informazioni, vedere Operatori di conversione definiti dall'utente. |
+= , -= , *= , /= , %= , &= , |= , ^= , <<= , >>= , >>>= |
Eseguire l'overload dell'operatore binario corrispondente. Ad esempio, quando si esegue l'overload dell'operatore binario + , viene eseguito l'overload implicito di += . |
^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 |
Nessuno. |
Specifiche del linguaggio C#
Per altre informazioni, vedere le sezioni seguenti delle specifiche del linguaggio C#:
Vedi anche
- Operatori ed espressioni C#
- Operatori di conversione definiti dall'utente
- Linee guida per la progettazione - Overload degli operatori
- Linee guida per la progettazione - Operatori di uguaglianza
- Why are overloaded operators always static in C#? (Perché gli operatori sottoposti a overload sono sempre statici in C#?)