Позвольте мне разбить это на несколько вопросов:
Что такое переменная?
Переменная - это место хранения, которое содержит значение.
Почему типы значений называются типами значений?
Значением переменной типа значения является значение , и оно копируется значением .Значение переменной ссылочного типа - ссылка и копируется ссылка .Вот почему типы значений называются типами значений, а ссылочные типы называются ссылочными типами.
Почему работает a.Height = 10?
Чтобы изменить значение, хранящееся впеременная ссылочного типа, у вас должна быть переменная для начала.В этом случае вы делаете: у вас есть переменная «а».Компилятор компилирует это как «передать управляемый адрес переменной« a »установщику высоты с аргументом 10».Поэтому установщик свойства Height знает, как найти местоположение значения, хранящегося в «a», и изменить его.
Почему не работает a.Size.Height = 10?
Чтобы изменить значение, хранящееся в переменной ссылочного типа, у вас должна быть переменная для начала.Выражение «a.Size» не является переменной;это ценность.a.Size не дает вам переменную, которая поддерживает свойство - на самом деле, она может не быть.Вместо этого он дает вам стоимость имущества.Типы значений копируются по значению;это копия стоимости имущества.Это означает, что у компилятора есть два варианта: он может скопировать значение во временную переменную и затем преобразовать эту переменную, заставляя вас думать, что вы мутировали резервное хранилище a.Size.Или это может дать вам ошибку, указывающую на то, что вы делаете что-то глупое.Это делает последнее.
Разве это не смущает и раздражает?
Да.Мораль этой истории состоит в том, что не делают изменяемые типы значений .Делайте только неизменяемые типы значений.Во-первых, никогда не устанавливайте тип значения;только делать присваивание в конструкторе.Если объект должен быть изменяемым, сделайте его ссылочным типом.
Нужно ли использовать "новый", чтобы создать новый экземпляр типа значения?
Нет.Вы также можете использовать «default»:
Foo f = default(Foo);
Если Foo является типом значения, то это заполняет содержимое хранилища f с помощью Foo, для всех полей которого установлены значения по умолчанию.
Или, если тип значения является изменяемым, вы можете просто установить значения всех полей.Однако вы должны установить все из них, если вы не используете конструктор или инициализатор по умолчанию.Вы должны установить все из них , включая частные поля .
Но если структура имеет все открытые поля, не противоречит ли это рекомендациям по передовому опыту двумя способами?Во-первых, потому что у него есть открытые поля, а во-вторых, потому что это изменяемый тип значения?
Да.Не делай этого.