Überladbare Operatoren von MSDN:
Zuweisungsoperatoren können nicht überladen werden, sondern +=
werden beispielsweise mit bewertet +
, was überladen werden kann.
Darüber hinaus kann keiner der Zuweisungsoperatoren überladen werden. Ich denke, das liegt daran, dass sich dies auf die Garbage Collection und die Speicherverwaltung auswirken wird, was eine potenzielle Sicherheitslücke in der stark typisierten CLR-Welt darstellt.
Mal sehen, was genau ein Operator ist. Laut dem berühmten Buch von Jeffrey Richter hat jede Programmiersprache eine eigene Operatorliste, die in speziellen Methodenaufrufen zusammengestellt wird, und CLR selbst weiß nichts über Operatoren. Mal sehen, was genau hinter den Operatoren +
und bleibt +=
.
Siehe diesen einfachen Code:
Decimal d = 10M;
d = d + 10M;
Console.WriteLine(d);
Sehen Sie sich den IL-Code für diese Anleitung an:
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
Nun sehen wir diesen Code:
Decimal d1 = 10M;
d1 += 10M;
Console.WriteLine(d1);
Und IL-Code dafür:
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
Sie sind gleich! Der +=
Operator ist also nur syntaktischer Zucker für Ihr Programm in C # , und Sie können den +
Operator einfach überladen .
Beispielsweise:
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;
}
Dieser Code wird kompiliert und erfolgreich ausgeführt als:
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
Aktualisieren:
Laut Ihrem Update - wie der @EricLippert sagt, sollten Sie die Vektoren wirklich als unveränderliches Objekt haben. Das Ergebnis der Addition der beiden Vektoren ist ein neuer Vektor, nicht der erste mit unterschiedlichen Größen.
Wenn Sie aus irgendeinem Grund den ersten Vektor ändern müssen, können Sie diese Überladung verwenden (aber für mich ist dies ein sehr seltsames Verhalten):
public static Vector operator +(Vector left, Vector right)
{
left.x += right.x;
left.y += right.y;
return left;
}