Estoy tratando de realizar sobrecargas de operadores +=
, pero no puedo. Solo puedo hacer que un operador se sobrecargue +
.
¿Cómo?
Editar
La razón por la que esto no funciona es que tengo una clase Vector (con un campo X e Y). Considere el siguiente ejemplo.
vector1 += vector2;
Si mi sobrecarga de operador está configurada en:
public static Vector operator +(Vector left, Vector right)
{
return new Vector(right.x + left.x, right.y + left.y);
}
Entonces el resultado no se agregará a vector1, sino que, en cambio, vector1 se convertirá en un nuevo Vector por referencia también.
Respuestas:
Operadores sobrecargables , de MSDN:
Aún más, ninguno de los operadores de asignación puede estar sobrecargado. Creo que esto se debe a que habrá un efecto para la recolección de basura y la administración de memoria, que es un potencial agujero de seguridad en el mundo CLR de tipo fuerte.
Sin embargo, veamos qué es exactamente un operador. Según el famoso libro de Jeffrey Richter , cada lenguaje de programación tiene su propia lista de operadores, que se compilan en un método especial de llamadas, y CLR en sí no sabe nada sobre operadores. Así que veamos qué queda exactamente detrás de los operadores
+
y+=
.Vea este código simple:
Veamos el código IL para estas instrucciones:
Ahora veamos este código:
Y código IL para esto:
¡Son iguales! Entonces, el
+=
operador es solo azúcar sintáctico para su programa en C # , y puede simplemente sobrecargar al+
operador.Por ejemplo:
Este código se compilará y se ejecutará correctamente como:
Actualizar:
De acuerdo con su Actualización, como dice @EricLippert, realmente debería tener los vectores como un objeto inmutable. El resultado de la suma de los dos vectores es un nuevo vector, no el primero con diferentes tamaños.
Si, por alguna razón, necesita cambiar el primer vector, puede usar esta sobrecarga (pero para mí, este es un comportamiento muy extraño):
fuente
v3 = v1 + v2;
resulte env1
un cambio yv3
es inusualCreo que este enlace le resultará informativo: Operadores para descargar
fuente
Esto se debe a la misma razón por la que el operador de asignación no se puede sobrecargar. No puede escribir código que realice la tarea correctamente.
De MSDN .
fuente
No se puede sobrecargar
+=
porque no es realmente un operador único, es solo azúcar sintáctico .x += y
es solo una forma abreviada de escribirx = x + y
. Porque+=
se define en términos de los operadores+
y=
, lo que le permite anularlo por separado podría crear problemas, en los casos en quex += y
yx = x + y
no se comportara exactamente de la misma manera.En un nivel inferior, es muy probable que el compilador de C # compile ambas expresiones en el mismo código de bytes, lo que significa que es muy probable que el tiempo de ejecución no pueda tratarlas de manera diferente durante la ejecución del programa.
Puedo entender que es posible que desee tratarlo como una operación separada: en una declaración como
x += 10
si supiera que puede mutar elx
objeto en su lugar y tal vez ahorrar algo de tiempo / memoria, en lugar de crear un nuevo objetox + 10
antes de asignarlo sobre la referencia anterior .Pero considere este código:
¿Debería
a == b
al final? Para la mayoría de los tipos, no,a
es 10 más queb
. Pero si puede sobrecargar al+=
operador para mutar en su lugar, entonces sí. Ahora considera esoa
yb
podría pasar a partes distantes del programa. Su posible optimización podría crear errores confusos si su objeto comienza a cambiar donde el código no lo espera.En otras palabras, si el rendimiento es tan importante, no es demasiado difícil de reemplazar
x += 10
con una llamada a método comox.increaseBy(10)
, y es mucho más claro para todos los involucrados.fuente
it's just syntactic sugar
ait's just syntactic sugar in C#
; de lo contrario, suena demasiado general, pero en algunos lenguajes de programación, no es solo azúcar sintáctico, sino que en realidad podría brindar beneficios de rendimiento.+=
probablemente podría optimizarse con un compilador inteligente, porque la aritmética es simple. Pero una vez que se trata de objetos, todas las apuestas se cancelan. Cualquier idioma enfrenta prácticamente los mismos problemas. Es por eso que la sobrecarga del operador es mala.Esto se debe a que este operador no se puede sobrecargar:
MSDN
Solo sobrecargue al
+
operador, debido ax += y
igual ax = x + y
fuente
La sobrecarga del operador para
+
se usa en+=
operador,A += B
es igual aA = operator+(A, B)
.fuente
Si sobrecarga al
+
operador así:tu puedes hacer
o
Esto se compilará y se ejecutará igualmente.
fuente
Siempre hay la misma respuesta a este problema: ¿Por qué necesita el
+=
, si lo obtiene gratis si sobrecarga el+
. Pero que pasa si tengo una clase como esta.¿Sigues diciendo que es bueno que
+=
esté "implementado automáticamente"? Si intenta hacer computación de alto rendimiento en C #, necesita tener tales características para reducir el tiempo de procesamiento y el consumo de memoria, si alguien tiene una buena solución, es muy apreciado, pero no me diga que tengo que hacer esto con métodos estáticos. , esto es solo una solución y no veo ninguna razón por la que C # realiza la+=
implementación si no está definido, y si está definido, se usará. Algunas personas dicen que no tener una diferencia entre+
y+=
previene errores, pero ¿no es este mi propio problema?fuente
+=
es su propio problema ... eso solo es cierto si nadie más tiene que leer, mantener o ejecutar su código.List<T>
un operador comolist += "new item"
, por ejemplo. En suAdd
lugar, llama a su método.Tenía exactamente la misma pregunta y no puedo responderla mejor que esta persona
fuente
Un mejor método de diseño es el casting explícito. Definitivamente puedes sobrecargar el Casting.
fuente