Operatori sovraccaricabili , da MSDN:
Gli operatori di assegnazione non possono essere sovraccaricati, ma +=
, ad esempio, vengono valutati utilizzando +
, che può essere sovraccaricato.
Inoltre, nessuno degli operatori di assegnazione può essere sovraccaricato. Penso che ciò sia dovuto al fatto che ci sarà un effetto per la Garbage Collection e la gestione della memoria, che è un potenziale buco di sicurezza nel mondo fortemente tipizzato di CLR.
Tuttavia, vediamo cos'è esattamente un operatore. Secondo il famoso libro di Jeffrey Richter , ogni linguaggio di programmazione ha il proprio elenco di operatori, che sono compilati in speciali chiamate di metodo, e CLR stesso non sa nulla degli operatori. Quindi vediamo cosa rimane esattamente dietro gli operatori +
e +=
.
Vedi questo semplice codice:
Decimal d = 10M;
d = d + 10M;
Console.WriteLine(d);
Visualizza il codice IL per queste istruzioni:
IL_0000: nop
IL_0001: ldc.i4.s 10
IL_0003: newobj instance void [mscorlib]System.Decimal::.ctor(int32)
IL_0008: stloc.0
IL_0009: ldloc.0
IL_000a: ldc.i4.s 10
IL_000c: newobj instance void [mscorlib]System.Decimal::.ctor(int32)
IL_0011: call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Addition(valuetype [mscorlib]System.Decimal,
valuetype [mscorlib]System.Decimal)
IL_0016: stloc.0
Ora vediamo questo codice:
Decimal d1 = 10M;
d1 += 10M;
Console.WriteLine(d1);
E il codice IL per questo:
IL_0000: nop
IL_0001: ldc.i4.s 10
IL_0003: newobj instance void [mscorlib]System.Decimal::.ctor(int32)
IL_0008: stloc.0
IL_0009: ldloc.0
IL_000a: ldc.i4.s 10
IL_000c: newobj instance void [mscorlib]System.Decimal::.ctor(int32)
IL_0011: call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Addition(valuetype [mscorlib]System.Decimal,
valuetype [mscorlib]System.Decimal)
IL_0016: stloc.0
Sono uguali! Quindi l' +=
operatore è solo zucchero sintattico per il tuo programma in C # e puoi semplicemente sovraccaricare l' +
operatore.
Per esempio:
class Foo
{
private int c1;
public Foo(int c11)
{
c1 = c11;
}
public static Foo operator +(Foo c1, Foo x)
{
return new Foo(c1.c1 + x.c1);
}
}
static void Main(string[] args)
{
Foo d1 = new Foo (10);
Foo d2 = new Foo(11);
d2 += d1;
}
Questo codice verrà compilato ed eseguito correttamente come:
IL_0000: nop
IL_0001: ldc.i4.s 10
IL_0003: newobj instance void ConsoleApplication2.Program/Foo::.ctor(int32)
IL_0008: stloc.0
IL_0009: ldc.i4.s 11
IL_000b: newobj instance void ConsoleApplication2.Program/Foo::.ctor(int32)
IL_0010: stloc.1
IL_0011: ldloc.1
IL_0012: ldloc.0
IL_0013: call class ConsoleApplication2.Program/Foo ConsoleApplication2.Program/Foo::op_Addition(class ConsoleApplication2.Program/Foo,
class ConsoleApplication2.Program/Foo)
IL_0018: stloc.1
Aggiornare:
Secondo il tuo aggiornamento, come dice @EricLippert, dovresti davvero avere i vettori come oggetto immutabile. Il risultato dell'aggiunta dei due vettori è un nuovo vettore, non il primo con dimensioni diverse.
Se per qualche motivo hai bisogno di cambiare il primo vettore, puoi usare questo sovraccarico (ma per quanto mi riguarda, questo è un comportamento molto strano):
public static Vector operator +(Vector left, Vector right)
{
left.x += right.x;
left.y += right.y;
return left;
}