Почему они являются структурами
Семантика значений
Между двумя идентичными экземплярами этих значений нет существенной разницы. Любая Point
с координатами, [2,3]
равна любой другой точке с теми же координатами, как равны любые две int
с одинаковым значением. Это соответствует руководству по проектированию:
Он логически представляет одиночное значение, подобное примитивным типам (целое число, двойное число и т. д.).
Производительность
Типы значений дешевле выделять и освобождать.
Часто требуется создать множество экземпляров этих значений. Создание структур обходится дешевле, и если они являются локальными значениями, они будут создаваться в стеке, снимая нагрузку со стороны сборщика мусора.
Размер
Рассмотрим размер этих значений:
Point
: 8 байт
Size
: 8 байт
Rectangle
: 16 байт
Для Point
и Size
их размер такой же, как у ссылки на экземпляр класса в 64-битной системе.
Цитаты взяты из рекомендаций Microsoft: Выбор между Классы и структуры
Почему они изменчивы
Эти структуры полностью изменяемы. Это делается (вопреки рекомендациям) ради производительности, поскольку позволяет избежать необходимости создавать новые значения для операций модификации.
Относительно примера кода OP в комментариях:
Point[] points = new Point[] { new Point(0,0), new Point(1,1), new Point(2,2) };
foreach (Point p in points)
{
p.X += 1;
}
Единственная причина, по которой этот foreach
терпит неудачу, заключается в том, что p
упакован в object
, чтобы обеспечить итерацию, и вы Cannot modify the result of an unboxing conversion
, (спасибо Раджив), итератор возвращает данные по значению, и вы будете вносить изменения только в копию значения.
Это отлично работает:
for (int i = 0; i < points.Length; i++)
{
points[i].X += 1;
}
person
Rotem
schedule
07.01.2013
struct
ness вызывает у вас проблемы? - person Damien_The_Unbeliever   schedule 07.01.2013foreach (Point r in points) { r.X += 1; }
‹-- не работает. По сути, я ожидаю, что они будут вести себя как ссылочные типы, но постоянно должен напоминать себе, что это не так. - person Flash   schedule 07.01.2013foreach
, который упаковывает значения. Он работает в простом циклеfor
. Все три структуры полностью изменяемы. - person Rotem   schedule 07.01.2013r.X += 1
подразумевает, чтоr
имеет ссылочную семантику. Другой пример: если мне разрешено делатьr.X += x
, мне должно быть позволено заставить работатьvoid offsetX(Point p, int xOffset)
, не прибегая кref
. Я могу заставить его работать, зная, что это тип значения, но почему Microsoft должна меня смущать? - person Flash   schedule 07.01.2013r.X += 1
работает, означает только то, что это поле доступно для записи, а не то, что это значение или ссылочный тип. В вашем методе вы должны использоватьref
, потому что в противном случае вы будете изменять копиюPoint
, а это не то, что вам нужно. - person Rotem   schedule 07.01.2013