Изменчивость типов значений - PullRequest
5 голосов
/ 12 ноября 2010

Рассмотрим статическую функцию TranslateAllCoords:

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

Затем, позже в коде, вы получите:

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

Но, вызывая TranslateAllCoords, вы фактически модифицируете типы значений (то есть целочисленные координаты), и обычно типы значений должны быть неизменяемыми. Не нарушены ли здесь некоторые правила, или это совершенно допустимая конструкция, которая обходит конструкцию «типы значений должны быть неизменяемыми», изменяя только встроенные типы значений?

Ответы [ 2 ]

17 голосов
/ 12 ноября 2010

Значения являются неизменными.Переменные, которые содержат типы значений, являются изменяемыми.Переменные различаются, поэтому они называются «переменными».

Руководство по проектированию, согласно которому типы значений должны быть неизменяемыми, по сути, говорит, что вы не должны пытаться изменить только часть переменной .Когда вы говорите

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

, то вы говорите: «мутировать только часть переменной p».Это сбивает с толку.Переменная p должна логически представлять точку, а точка - это значение.Если вы хотите изменить p, то логически измените все это на , назначив ему новую точку .Не изменяйте одну точку в другую.

Но даже если мы сделали точку неизменной:

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

, тогда переменная этого типа все еще может варьироваться!

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

Но теперь стало ясно, что вся переменная меняется на новую точку, а не мы пытаемся изменить определенную часть переменной.

С неизменяемым типом значения вы можете сделать свой перевод более разумно:

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

Видите, опять же, мутирует, но мутирует все сразу, а не по частям за раз.

1 голос
/ 12 ноября 2010

Никаких правил там не нарушено.Вы просто создаете новое целочисленное значение и переназначаете переменную, содержащую их.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...