C# operator overload for `+=`?
Overloadable Operators, from MSDN:
Assignment operators cannot be overloaded, but
+=
, for example, is evaluated using+
, which can be overloaded.
Even more, none of assignment operators can be overloaded. I think this is because there will be an effect for the Garbage collection and memory management, which is a potential security hole in CLR strong typed world.
Nevertheless, let's see what exactly an operator is. According to the famous Jeffrey Richter's book, each programming language has its own operators list, which are compiled in a special method calls, and CLR itself doesn't know anything about operators. So let's see what exactly stays behind the +
and +=
operators.
See this simple code:
Decimal d = 10M;
d = d + 10M;
Console.WriteLine(d);
Let view the IL-code for this instructions:
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
Now lets see this code:
Decimal d1 = 10M;
d1 += 10M;
Console.WriteLine(d1);
And IL-code for this:
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
They are equal! So the +=
operator is just syntactic sugar for your program in C#, and you can simply overload +
operator.
For example:
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;
}
This code will be compiled and successfully run as:
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
Update:
According to your Update - as the @EricLippert says, you really should have the vectors as an immutable object. Result of adding of the two vectors is a new vector, not the first one with different sizes.
If, for some reason you need to change first vector, you can use this overload (but as for me, this is very strange behaviour):
public static Vector operator +(Vector left, Vector right)
{
left.x += right.x;
left.y += right.y;
return left;
}
I think you'll find this link informative: Overloadable Operators
Assignment operators cannot be overloaded, but +=, for example, is evaluated using +, which can be overloaded.
This is because of the same reason that the assignment operator cannot be overloaded. You cannot write code that would perform the assignment correctly.
class Foo
{
// Won't compile.
public static Foo operator= (Foo c1, int x)
{
// duh... what do I do here? I can't change the reference of c1.
}
}
Assignment operators cannot be overloaded, but +=, for example, is evaluated using +, which can be overloaded.
From MSDN.