I principali operatori aritmetici e di confronto possono essere adattati per essere usati dalle tue classi e dalle tue struct. Questo è noto come «sovraccarico degli operatori».
Questo articolo è una trattazione approfondita della sintassi, nonché di quali operatori si possono sovraccaricare e quali no.
La maggior parte degli operatori ha la forma:
static <return type> operaator <operator symbols>(<parameters>);
Gli operatori di cast hanno la forma:
static (explicit|implicit) operator <cast-to-type>(<cast-from-type> <parameter name>);
Gli operatori si comportano allo stesso modo dei metodi statici.
Esempi di sintassi:
struct Point
{
decimal x;
decimal y;
public static bool operator ==(Point pt, Point ptOther)
{
return pt.x == ptOther.x && pt.y == ptOther.y;
}
public static bool operator !=(Point pt, Point ptOther)
{
return !(pt == ptOther);
}
public static Point operator *(Point pt, decimal scale)
{
var ptNew = new Point();
ptNew.x = pt.x * scale;
ptNew.y = pt.y * scale;
return ptNew;
}
public static implicit operator Point((decimal x, decimal y) xy)
{
var pt = new Point();
pt.x = xy.x;
pt.y = xy.y;
return pt;
}
public static explicit operator (decimal x, decimal y)(Point pt)
{
return (pt.x, pt.y);
}
}
Spesso è produttivo implementare un metodo Equals() e chiamarlo dall'operatore ==. Allo stesso modo, per i confronti puoi implementare l'interfaccia IComparable. In entrambi i casi prendi due piccioni con poco più di una fava.
Nota che non puoi creare operatori a partire da simboli che non fanno parte dell'insieme standard degli operatori. Puoi usare solo simboli esistenti per quelle operazioni che la documentazione indica come sovraccaricabili. Gli operatori che si possono sovraccaricare sono elencati qui.
Nota che l'ordine dei parametri è importante quando differiscono per tipo. Nel codice di esempio qui sopra pt * 10m è un'espressione valida, mentre 10m * pt non verrà compilato.
Questa documentazione sul sovraccarico degli operatori descrive la sintassi in dettaglio.