Operadores sobrecarregáveis , do MSDN:
Os operadores de atribuição não podem ser sobrecarregados, mas +=
, por exemplo, são avaliados usando +
, que pode ser sobrecarregado.
Ainda mais, nenhum dos operadores de atribuição pode ser sobrecarregado. Eu acho que isso ocorre porque haverá um efeito para a coleta de lixo e gerenciamento de memória, que é uma brecha de segurança potencial no mundo de tipo forte CLR.
No entanto, vamos ver o que exatamente é um operador. De acordo com o famoso livro de Jeffrey Richter , cada linguagem de programação tem sua própria lista de operadores, que são compilados em uma chamada de método especial, e o próprio CLR não sabe nada sobre operadores. Então, vamos ver o que exatamente fica para trás dos operadores +
e +=
.
Veja este código simples:
Decimal d = 10M;
d = d + 10M;
Console.WriteLine(d);
Vamos ver o código IL para estas instruções:
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
Agora vamos ver este código:
Decimal d1 = 10M;
d1 += 10M;
Console.WriteLine(d1);
E código IL para isso:
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
Eles são iguais! Portanto, o +=
operador é apenas um açúcar sintático para seu programa em C # e você pode simplesmente sobrecarregar o +
operador.
Por exemplo:
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;
}
Este código será compilado e executado com sucesso como:
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
Atualizar:
De acordo com sua atualização - como diz o @EricLippert, você realmente deveria ter os vetores como um objeto imutável. O resultado da adição dos dois vetores é um novo vetor, não o primeiro com tamanhos diferentes.
Se, por algum motivo, você precisar alterar o primeiro vetor, pode usar essa sobrecarga (mas, quanto a mim, esse é um comportamento muito estranho):
public static Vector operator +(Vector left, Vector right)
{
left.x += right.x;
left.y += right.y;
return left;
}