readonly (Справочник по C#)
readonly Ключевое слово — это модификатор, который можно использовать в пяти контекстах:
- В объявлении поля readonly указывает на то, что присвоение значения полю может происходить только при объявлении или в конструкторе этого класса. Полю только для чтения можно несколько раз назначить значения в объявлении поля и в конструкторе. Поле readonly нельзя изменять после выхода из конструктора. Это правило влечет за собой разные последствия для типов значений и ссылочных типов:
- Так как типы значений непосредственно содержат их данные, поле, которое является типом readonly значения, является неизменяемым.
- Ссылочные типы содержат только ссылку на соответствующие данные, а значит поле readonly ссылочного типа будет всегда ссылаться на один объект. Но сам этот объект не является неизменяемым. Модификатор readonly запрещает замену поля другим экземпляром ссылочного типа. Но этот модификатор не препятствует изменению данных экземпляра, на которое ссылается поле только для чтения, в том числе через это поле.
Внешний видимый тип, содержащий внешне видимое поле только для чтения, которое является изменяемым ссылочным типом, может быть уязвимостью безопасности и может вызвать предупреждение CA2104 : «Не объявляйте только изменяемые типы ссылок».
- ref readonly Объявление параметра методу.
Пример поля только для чтения
В этом примере значение поля year нельзя изменить в методе ChangeYear , несмотря на то, что в конструкторе класса ему присваивается значение:
class Age < private readonly int _year; Age(int year) < _year = year; >void ChangeYear() < //_year = 1967; // Compile error if uncommented. >>Можно присвоить значение полю readonly только в следующих контекстах:
-
Когда переменная инициализируется в объявлении, например:
public readonly int y = 5;Эти контексты конструктора являются единственными, в которых можно передавать поле readonly в качестве параметра out или ref.
Ключевое слово readonly отличается от ключевого слова const. Поле const может быть инициализировано только при объявлении поля. Поле readonly может быть назначено несколько раз в объявлении поля и в любом конструкторе. Таким образом, поля readonly могут иметь разные значения в зависимости от использованного конструктора. К тому же, поскольку поле const является константой времени компиляции, поле readonly можно использовать для констант времени выполнения, как в следующем примере:
public static readonly uint timeStamp = (uint)DateTime.Now.Ticks;public class SamplePoint < public int x; // Initialize a readonly field public readonly int y = 25; public readonly int z; public SamplePoint() < // Initialize a readonly instance field z = 24; >public SamplePoint(int p1, int p2, int p3) < x = p1; y = p2; z = p3; >public static void Main() < SamplePoint p1 = new SamplePoint(11, 21, 32); // OK Console.WriteLine($"p1: x=, y=, z="); SamplePoint p2 = new SamplePoint(); p2.x = 55; // OK Console.WriteLine($"p2: x=, y=, z="); > /* Output: p1: x=11, y=21, z=32 p2: x=55, y=25, z=24 */ >В предыдущем примере при использовании такого оператора:
p2.y = 66; // Errorбудет отображено сообщение об ошибке компилятора:
Присваивание значений доступному только для чтения полю допускается только в конструкторе и в инициализаторе переменных.
Члены экземпляров только для чтения
Модификатор можно также использовать readonly для объявления того, что член экземпляра не изменяет состояние структуры.
public readonly double Sum()
Пример возвращаемой ссылки только для чтения
Модификатор readonly в ref return указывает, что возвращаемую ссылку нельзя изменить. Следующий пример возвращает ссылку на источник. Он использует модификатор readonly , чтобы указать, что вызывающие объекты не могут изменять источник:
private static readonly SamplePoint s_origin = new SamplePoint(0, 0, 0); public static ref readonly SamplePoint Origin => ref s_origin;Необязательно должен возвращаться тип readonly struct . Любой тип, возвращаемый из ref , может возвращаться из ref readonly .
Пример возвращаемого значения readonly readonly
Возврат refonly также можно использовать в сочетании с readonly элементами экземпляра в struct типах:
public struct ReadonlyRefReadonlyExample < private int _data; public readonly ref readonly int ReadonlyRefReadonly(ref int reference) < // _data = 1; // Compile error if uncommented. return ref reference; >>Метод по сути возвращает ссылку readonly вместе с членом экземпляра (в данном случае методом) readonly (не удается изменить поля экземпляра).
Спецификация языка C#
Дополнительные сведения см. в спецификации языка C#. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.
Вы также можете ознакомиться с предложениями языковых спецификаций:
- Ссылка и структура readonly
- Члены структуры readonly
См. также
- Добавление модификатора чтения (правило стиля IDE0044)
- Справочник по C#
- Руководство по программированию на C#
- Ключевые слова в C#
- Модификаторы
- const
- Поля
Совместная работа с нами на GitHub
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
Что такое readonly в C#?
Ключевое слово readonly в C# применяется для создания переменных, которые могут быть присвоены только во время инициализации или в конструкторе класса. Оно обозначает, что значение переменной может быть установлено только один раз и не может быть изменено после этого. Вот основные моменты и пример использования readonly :
Основные моменты:
- Неизменяемость после инициализации: Переменные, объявленные с модификатором readonly , могут быть присвоены только в момент их создания или в конструкторе, и их значение не может быть изменено после этого.
- Инициализация во время объявления или в конструкторе: Переменные readonly могут быть инициализированы во время объявления или в конструкторе класса. Если они инициализируются в момент объявления, они считаются константами времени компиляции.
public class Example < // Переменная readonly может быть инициализирована в момент объявления public readonly int ConstantValue = 42; // Переменная readonly, инициализирована в конструкторе public readonly string ReadOnlyString; // Конструктор класса public Example(string readOnlyString) < // Инициализация переменной readonly в конструкторе ReadOnlyString = readOnlyString; >// Метод, который использует переменные readonly public void DisplayValues() < Console.WriteLine($"ConstantValue: "); Console.WriteLine($"ReadOnlyString: "); > >Readonly c что это
Кроме полей класс может определять для хранения данных константы. В отличие от полей из значение устанавливается один раз непосредственно при их объявлении и впоследствии не может быть изменено. Кроме того, константы хранят некоторые данные, которые относятся не к одному объекту, а ко всему классу в целом. И для обращения к константам применяется не имя объекта, а имя класса:
Person tom = new Person(); tom.name = "Tom"; tom.Print(); // Person: Tom Console.WriteLine(Person.type); // Person // Person.type = "User"; // !Ошибка: изменить константу нельзя class Person < public const string type = "Person"; public string name = "Undefined"; public void Print() =>Console.WriteLine($": "); >
Здесь в классе Person определена константа type , которая хранит название класса:
public const string type = "Person";
Название класса не зависит от объекта. Мы можем создать много объектов Person, но название класса от этого не должно измениться — оно относится ко всем объектам Person и не должно меняться. Поэтому название типа можно сохранить в виде константы.
Стоит отметить, что константе сразу при ее определении необходимо присвоить значение.
Подобно обычным полям мы можем обращаться к константам класса внутри этого класса. Например, в методе Print значение константы выводится на консоль.
Однако если мы хотим обратиться к константе вне ее класса, то для обращения необходимо использовались имя класса:
Console.WriteLine(Person.type); // Person
Таким образом, если необходимо хранить данные, которые относятся ко всему классу в целом, то можно использовать константы.
Поля для чтения и модификатор readonly
Поля для чтения представляют такие поля класса или структуры, значение которых нельзя изменить. Таким полям можно присвоить значение либо при непосредственно при их объявлении, либо в конструкторе. В других местах программы присваивать значение таким полям нельзя, можно только считывать их значение.
Поле для чтения объявляется с ключевым словом readonly :
Person tom = new Person("Tom"); Console.WriteLine(tom.name); //tom.name = "Sam"; // !Ошибка: нельзя изменить class Person < public readonly string name = "Undefined"; // можно так инициализировать public Person(string name) < this.name = name; // в конструкторе также можно присвоить значение полю для чтения >public void ChangeName(string otherName) < //this.name = otherName; // так нельзя >>Здесь поле name хранит имя пользователя и представляет поле для чтения. Ему можно присвоить значение непосредственно при объявлении:
public readonly string name = "Undefined";
Либо можно присвоить значение в конструкторе
public Person(string name)
В остальных местах программы, в том числе в самом классе Person присвоить значение полю для чтения нельзя.
Сравнение констант
- Константы должны быть определены во время компиляции, а поля для чтения могут быть определены во время выполнения программы. Соответственно значение константы можно установить только при ее определении. Поле для чтения можно инициализировать либо при его определении, либо в конструкторе класса.
- Константы не могут использовать модификатор static, так как уже неявно являются статическими. Поля для чтения могут быть как статическими, так и не статическими.
Структуры для чтения
Кроме полей для чтения в C# можно определять структуры для чтения. Для этого они предваряются модификатором readonly :
readonly struct Person
Особенностью таких структур является то, что все их поля должны быть также полями для чтения:
readonly struct Person < public readonly string name; public Person(string name) < this.name = name; >>
То же самое касается и свойств, которые должны быть доступны только для чтения:
readonly struct Person < public readonly string Name < get; >// указывать readonly необязательно public int Age < get; >// свойство только для чтения public Person(string name, int age) < Name = name; Age = age; >>
C#: в чем разница между readonly и const?
Привет всем! В C# есть const и readonly. В сети нашел только информацию о разнице static readonly и const. А какая разница между просто readonly и const?
Отслеживать
задан 8 апр 2017 в 19:15
2,606 8 8 золотых знаков 52 52 серебряных знака 106 106 бронзовых знаков
Плохо искали: stackoverflow.com/questions/55984/…
8 апр 2017 в 19:19
Если проще ответ вверху, то readonly можно менять в конструкторе
14 апр 2019 в 7:251 ответ 1
Сортировка: Сброс на вариант по умолчанию
Значения полей с модификатором const при компиляции подставляются в тех местах кода, где к ним происходит обращение. Это значит, что в случае, когда такое поле объявлено в классе одной сборки, а используется классами другой сборки, для того чтобы измененное значение было применено в зависимой сборке, потребуется перекомпиляция зависимой сборки. Задать значение можно только в момент объявления. В общем то const -поля это не совсем поля.
Поля с модификатором readonly являются полноценными полями, с той разницей, что изменять их значение разрешено только в конструкторе. Соответственно static readonly — в статическом конструкторе (код инициализации полей при объявлении переносится в конструктор компилятором). Таким образом, значения readonly -полей могут, например вычисляться на основе параметров переданных в конструктор, что невозможно для const -полей.
В большинстве случаев рекомендуется использовать именно readonly -поля вместо const -полей когда ваш проект включает более одного модуля.
А еще у нас тут есть шикарный список литературы рекомендуемой к прочтению для изучения C# и .NET. Книги в списке условно разделены по уровню сложности. Большую часть из них можно найти в сети в электронном виде, было бы желание. Так уж получается, что без чтения книжек программисту не обойтись.