Estou tentando sobrecarregar o operador +=
, mas não consigo. Eu só posso fazer uma sobrecarga do operador para+
.
Por quê?
Editar
O motivo pelo qual isso não está funcionando é que tenho uma classe Vector (com um campo X e Y). Considere o seguinte exemplo.
vector1 += vector2;
Se minha sobrecarga de operador estiver definida para:
public static Vector operator +(Vector left, Vector right)
{
return new Vector(right.x + left.x, right.y + left.y);
}
Então, o resultado não será adicionado ao vetor1, mas, em vez disso, o vetor1 se tornará um novo vetor por referência também.
Respostas:
Operadores sobrecarregáveis , do MSDN:
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:
Vamos ver o código IL para estas instruções:
Agora vamos ver este código:
E código IL para isso:
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:
Este código será compilado e executado com sucesso como:
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):
fonte
v3 = v1 + v2;
resulta emv1
ser alterada, além dev3
incomumAcho que você encontrará este link informativo: Operadores sobrecarregáveis
fonte
Isso ocorre pelo mesmo motivo que o operador de atribuição não pode ser sobrecarregado. Você não pode escrever código que executaria a atribuição corretamente.
Do MSDN .
fonte
Você não pode sobrecarregar
+=
porque não é realmente um operador único, é apenas um açúcar sintático .x += y
é apenas uma forma abreviada de escreverx = x + y
. Porque+=
é definido em termos dos operadores+
e=
, permitir que você substitua-o separadamente poderia criar problemas, nos casos em quex += y
ex = x + y
não se comportasse exatamente da mesma maneira.Em um nível inferior, é muito provável que o compilador C # compile ambas as expressões no mesmo bytecode, o que significa que é muito provável que o tempo de execução não possa trate de maneira diferente durante a execução do programa.
Eu posso entender que você pode querer tratá-lo como uma operação separada: em uma declaração como
x += 10
você sabe que você pode transformar ox
objeto no local e talvez economizar algum tempo / memória, em vez de criar um novo objetox + 10
antes de atribuí-lo sobre a referência antiga .Mas considere este código:
Deve
a == b
no final? Para a maioria dos tipos, não,a
é 10 a mais queb
. Mas se você pudesse sobrecarregar o+=
operador para sofrer mutação no local, então sim. Agora considere issoa
eb
poderia ser transmitido para partes distantes do programa. Sua possível otimização pode criar bugs confusos se o seu objeto começar a mudar onde o código não espera.Em outras palavras, se o desempenho é tão importante, não é muito difícil substituí-lo
x += 10
por uma chamada de método comox.increaseBy(10)
, e é muito mais claro para todos os envolvidos.fonte
it's just syntactic sugar
parait's just syntactic sugar in C#
; caso contrário, soa muito geral, mas em algumas linguagens de programação, não é apenas um açúcar sintático, mas pode realmente oferecer benefícios de desempenho.+=
provavelmente poderia ser otimizado por um compilador inteligente, porque a aritmética é simples. Mas, uma vez que você está lidando com objetos, todas as apostas estão canceladas. Qualquer idioma enfrenta praticamente os mesmos problemas. É por isso que a sobrecarga do operador é prejudicial.Isso ocorre porque este operador não pode ser sobrecarregado:
MSDN
Apenas sobrecarregue o
+
operador, por causa dex += y
igual ax = x + y
fonte
Sobrecarga do operador para
+
é usado em+=
operador,A += B
é igual aA = operator+(A, B)
.fonte
Se você sobrecarregar o
+
operador assim:você pode fazer
ou
Isso irá compilar e rodar igualmente.
fonte
Sempre há a mesma resposta para esse problema: Por que você precisa do
+=
, se você o obtém gratuitamente se sobrecarregar o+
. Mas o que acontece se eu tiver uma aula como essa.Você ainda diz que é bom que o
+=
seja "autoimplementado". Se você tentar fazer computação de alto desempenho em C #, você precisa ter esses recursos para reduzir o tempo de processamento e o consumo de memória, se alguém tiver uma boa solução, isso é muito apreciado, mas não me diga que tenho que fazer isso com métodos estáticos , esta é apenas uma solução alternativa e não vejo razão para que o C # faça a+=
implementação se não estiver definido e, se estiver definido, será usado. Algumas pessoas dizem que não ter diferença+
e+=
evita erros, mas não é problema meu?fonte
+=
é problema seu ... isso só é verdade se ninguém mais tiver que ler, manter ou executar seu código.List<T>
usando um operador comolist += "new item"
, por exemplo. EmAdd
vez disso, você chama seu método.Eu tinha exatamente a mesma pergunta e não posso respondê-la melhor do que esta pessoa
fonte
Um método de design melhor é a fundição explícita. Você pode definitivamente sobrecarregar o Casting.
fonte