¿Los tipos de valor son inmutables por definición?
Frecuentemente leo questruct
s deben ser inmutables, ¿no son por definición?
Tu considerasint
para ser inmutable?
int i = 0;
i = i + 123;
Parece bien - tenemos una nuevaint
y asignarlo de nuevo ai
. ¿Qué hay de esto?
i++;
e acuerdo, podemos considerarlo como un atajo.
i = i + 1;
Qué pasa con lastruct
Point
?
Point p = new Point(1, 2);
p.Offset(3, 4);
¿Esto realmente muta el punto(1, 2)
? ¿No deberíamos considerarlo como un atajo para lo siguiente conPoint.Offset()
devolviendo un nuevo punto?
p = p.Offset(3, 4);
El trasfondo de este pensamiento es este: ¿cómo puede un tipo de valor sin identidad ser mutable? Tienes que mirarlo al menos dos veces para determinar si cambió. Pero, ¿cómo puedes hacer esto sin una identidad?
No quiero complicar el razonamiento sobre esto considerandoref
parámetros y boxeo. También soy consciente de quep = p.Offset(3, 4);
expresa la inmutabilidad mucho mejor quep.Offset(3, 4);
hace. Pero la pregunta sigue siendo: ¿no son los tipos de valores inmutables por definición?
ACTUALIZA
Creo que hay al menos dos conceptos involucrados: la mutabilidad de una variable o campo y la mutabilidad del valor de una variable.
public class Foo
{
private Point point;
private readonly Point readOnlyPoint;
public Foo()
{
this.point = new Point(1, 2);
this.readOnlyPoint = new Point(1, 2);
}
public void Bar()
{
this.point = new Point(1, 2);
this.readOnlyPoint = new Point(1, 2); // Does not compile.
this.point.Offset(3, 4); // Is now (4, 6).
this.readOnlyPoint.Offset(3, 4); // Is still (1, 2).
}
}
En el ejemplo tenemos campos: uno mutable y uno inmutable. Debido a que un campo de tipo de valor contiene el valor completo, un tipo de valor almacenado en un campo inmutable también debe ser inmutable. Todavía estoy bastante sorprendido por el resultado: no esperaba que el campo de solo lectura permaneciera sin modificaciones.
as variables (además de las constantes) son siempre mutables, por lo tanto, no implican ninguna restricción en la mutabilidad de los tipos de valo
La respuesta parece no ser tan sencilla, así que volveré a formular la pregunta.
Dado lo siguiente.
public struct Foo
{
public void DoStuff(whatEverArgumentsYouLike)
{
// Do what ever you like to do.
}
// Put in everything you like - fields, constants, methods, properties ...
}
¿Puedes dar una versión completa deFoo
y un ejemplo de uso, que puede incluirref
parámetros y boxeo, por lo que no es posible reescribir todas las ocurrencias de
foo.DoStuff(whatEverArgumentsYouLike);
co
foo = foo.DoStuff(whatEverArgumentsYouLike);