2010-11-12 8 views
5

Betrachten Sie die TranslateAllCoords statische Funktion:Veränderlichkeit von Werttypen

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

Dann später im Code, Sie haben:

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

Aber durch TranslateAllCoords Sie sind in der Tat zu modifizieren Werttypen Aufruf (dh , die Ganzzahl coords) und allgemein Werte sollten unveränderlich sein. Sind hier einige Regeln gebrochen oder ist das ein absolut gültiges Konstrukt, das das Konstrukt "Werttypen sollten unveränderbar sein" umgeht, indem nur eingebaute Werttypen modifiziert werden?

Antwort

17

Die Werte sind unveränderlich. Die Variablen, die die Werttypen enthalten, sind veränderbar. Variablen variieren, deshalb werden sie "Variablen" genannt.

Die Entwurfsanleitung, dass Werttypen unveränderlich sein sollten, besagt im Wesentlichen, dass Sie nicht versuchen sollten, nur einen Teil einer Variablen zu ändern. Wenn Sie sagen:

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

dann was Sie sagen, ist "muate nur Teil der Variablen p". Das ist verwirrend. Die Variable p sollte logisch einen Punkt darstellen, und ein Punkt ist ein Wert. Wenn Sie p variieren wollen, dann variieren Sie logisch das Ganze von Zuweisung eines neuen Punktes. Verwandle keinen Punkt in einen anderen.

Aber selbst wenn wir Punkt gemacht unveränderlich:

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

dann eine Variable dieses Typs variieren kann immer noch!

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

Aber jetzt ist es klar, dass die gesamte Variable auf einen neuen Punkt ändert, anstatt wir einen bestimmten Teil der Variablen mutieren zu versuchen.

Mit einem unveränderlichen Werttyp können Sie dann Ihre Übersetzung sinnvoll mehr:

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); 

See, wieder, S. mutiert, aber es ist alles auf einmal mutiert, nicht in kleine Stücke zu einem Zeitpunkt.

+0

Danke für die klare Erklärung! –

1

Keine Regeln sind dort gebrochen. Sie erstellen einfach einen neuen Ganzzahlwert und weisen die Variable, die sie enthält, neu zu.

Verwandte Themen