2010-11-12 6 views
5

Considere la TranslateAllCoords función estática:mutabilidad de los tipos de valor

static class CoordinateTransformation 
{ 
    public static void TranslateAllCoords(ref int x, ref int y, ref int z, 
             int amount) 
    { 
    x+=amount; 
    y+=amount; 
    z+=amount; 
    } 
} 

Luego, más tarde en el código, usted tiene:

int x=0, y=0, z=0; 
... 
CoordinateTransformation.TranslateAllCoords(ref x, ref y, ref z, 5); 
... 

Pero, llamando TranslateAllCoords que están en vigor los tipos de valor modificación (es decir, , los coords enteros) y generalmente los tipos de valores deben ser inmutables. ¿Se han roto algunas reglas aquí o es una construcción perfectamente válida que se mueve alrededor de la construcción de "los tipos de valores deben ser inmutables" modificando solo los tipos de valores incorporados?

Respuesta

17

Los valores son inmutables. Las variables que contienen los tipos de valores son mutables. Las variables varían, es por eso que se llaman "variables".

La guía de diseño que los tipos de valores deben ser inmutables es básicamente decir que no debe intentar cambiar solo parte de una variable. Cuando dices

struct Point { public int X; public int Y; public int Z; } 
... 
Point p = new Point(); 
p.X = 123; 

entonces lo que dices es "mutar solo parte de la variable p". Eso es confuso La variable p debe representar lógicamente un punto, y un punto es un valor. Si desea variar p, entonces lógicamente varíe todo por asignándole un nuevo punto. No mutes un punto en otro.

Pero incluso si hicimos punto inmutable:

struct Point { public int X { get; private set; } ... etc } 

entonces una variable de ese tipo todavía pueden variar!

Point p = new Point(123, 456, 789); 
p = new Point(100, 200, 300); 

Pero ahora está claro que toda la variable está cambiando a un nuevo punto, en lugar de nosotros tratando de mutar una porción particular de la variable.

Con un tipo de valor inmutable a continuación, puede hacer su traducción más sensata:

static Point Translate(Point p, int offset) 
{ 
    return new Point(p.X + offset, p.Y + offset, p.Z + offset); 
} 
... 
Point p = new Point(100, 200, 300); 
p = Translate(p, 5); 

Sede, de nuevo, p muta, pero muta todos a la vez, no en pequeños trozos a la vez.

+0

Gracias por la clara explicación! –

1

No existen reglas vigentes al respecto. Simplemente está creando un nuevo valor entero y reasignando la variable que los contiene.

Cuestiones relacionadas