Объявление структур только для чтения (C#7.2)
C# долгое время неявно копировал структуры. Все это задокументировано в спецификации. Причина, по которой компилятор делает эту копию, состоит в том, чтобы избежать изменения поля, доступного только для чтения, кодом в свойстве (или методом, если вы его вызываете). Смысл поля только для чтения состоит в том, что ничто не может изменить его значение. Было бы странно, если бы
readOnlyField.SomeMethod() мог изменять поле. C# рассчитан на то, что любые мутаторы (set) свойств будут изменять данные, поэтому они запрещены для полей только для чтения. Но даже аксессор (get) свойства может попытаться изменить значение. Поэтому скрытая копия - это эффективная мера безопасности.Но что, если структура может пообещать, что она этого не сделает? В конце концов, большинство структур разработано, чтобы быть неизменяемыми. В C#7.2 вы можете применить модификатор readonly к объявлению структуры, чтобы это сделать:
public readonly struct YearMonthDayВы можете применять модификатор только в том случае, если ваша структура действительно доступна только для чтения и поэтому соответствует следующим условиям:
{
public int Year { get; }
public int Month { get; }
public int Day { get; }
public YearMonthDay(int year, int month, int day) =>
(Year, Month, Day) = (year, month, day);
}
1. Каждое поле и автоматически реализованное свойство экземпляра должны быть доступны только для чтения. Статические поля и свойства все ещё могут быть доступны для чтения и записи.
2. Вы можете обращаться к
this только внутри конструкторов. Можно рассматривать this в структурах:- как out-параметр в конструкторах (инициализирует поле);
- как ref-параметр в членах обычных структур (изменяет значение поля по ссылке);
- как in-параметр в членах структур только для чтения (читает значение поля по ссылке).
Там, где вы можете сделать свои пользовательские структуры доступными только для чтения, я призываю вас сделать это. Просто помните, что это одностороннее изменение для публичного кода. Вы можете безопасно удалить модификатор позже, только если у вас есть возможность перекомпилировать весь код, который использует эту структуру.
Источник: Jon Skeet “C# In Depth”. 4th ed – Manning Publications Co, 2019. Глава 13.