Переменная класса, параметр, поле, возвращаемое значение или другое подобное хранилище должно рассматриваться как «идентификатор объекта». Если некоторый объект Foo
имеет свойство с именем Bar
некоторого типа класса, которое поддерживается полем _Bar
, и _Bar
содержит «идентификатор объекта # 24601», то оператор Foo.Bar.Text = "George"
вызовет Text
сеттер на объекте № 24601 со значением "Джордж". Обратите внимание, что этот оператор не изменит сам объект Foo
(его поле _Bar
будет содержать «идентификатор объекта # 24601» до выполнения оператора и будет по-прежнему удерживать его после); однако, скорее всего, это повлияет на объект # 24601.
Место хранения типа структуры следует рассматривать как содержащее содержимое всех его полей (как открытых, так и закрытых). Если бы Foo.Boz
было свойством типа Rectangle
(которое является структурой) и вспомогательным полем _Boz
, доступ к Foo.Boz
создал бы новый временный экземпляр типа Rectangle
, все поля которого были бы скопированы из тех, что Foo._Boz
. Попытка чтения Foo.Boz.X
скопирует все поля _Boz
во временный экземпляр, а затем получит доступ к полю X
этого экземпляра.
Обратите внимание, что некоторые действительно старые и злые компиляторы C # интерпретируют код, такой как Foo.Boz.X = 5;
, как Rectangle temp; temp.X = 5;
, отбрасывая полученное значение temp, но не выдавая никакого предупреждения. Такое поведение компилятора заставило некоторых людей объявить, что структуры должны быть «неизменяемыми», чтобы гарантировать, что такой код будет генерировать ошибку компилятора, а не выдавать поддельное поведение. К сожалению, эта вера сохраняется и по сей день, несмотря на то, что любой приличный компилятор запретил бы такой код, даже если X
было изменяемым полем.
Обратите внимание, что правильный идиоматический способ обновления свойства изменяемого структурного типа:
Rectangle temp = MyListOFRectangles[5];
temp.X = 5;
MyListOFRectangles[5] = temp;
Если известно, что Rectangle
имеет открытое целочисленное поле с именем X
, а MyListOfRectangles
- это List<Rectangle>
, вам не нужно знать о каких-либо других свойствах Rectangle
, конструкторы и т. д., чтобы знать, что приведенный выше код изменит MyListOfRectangles[5].X
, но не повлияет ни на другое свойство MyListOfRectangles[5]
, ни на любое свойство MyListOfRectangles[4]
. Красиво, понятно и просто. Структуры открытых полей позволяют выполнять поэтапное редактирование значений понятным и непротиворечивым способом, в отличие от любого другого типа данных.