readonly (C# Reference)
The readonly keyword is a modifier that can be used in five contexts:
- In a field declaration, readonly indicates that assignment to the field can only occur as part of the declaration or in a constructor in the same class. A readonly field can be assigned and reassigned multiple times within the field declaration and constructor. A readonly field can’t be assigned after the constructor exits. This rule has different implications for value types and reference types:
- Because value types directly contain their data, a field that is a readonly value type is immutable.
- Because reference types contain a reference to their data, a field that is a readonly reference type must always refer to the same object. That object might not be immutable. The readonly modifier prevents replacing the field value with a different instance of the reference type. However, the modifier doesn’t prevent the instance data of the field from being modified through the read-only field.
An externally visible type that contains an externally visible read-only field that is a mutable reference type may be a security vulnerability and may trigger warning CA2104 : «Do not declare read only mutable reference types.»
- To declare a ref readonly parameter to a method.
Readonly field example
In this example, the value of the field year can’t be changed in the method ChangeYear , even though it was assigned a value in the class constructor:
class Age < private readonly int _year; Age(int year) < _year = year; >void ChangeYear() < //_year = 1967; // Compile error if uncommented. >>You can assign a value to a readonly field only in the following contexts:
-
When the variable is initialized in the declaration, for example:
public readonly int y = 5;These constructor contexts are also the only contexts in which it’s valid to pass a readonly field as an out or ref parameter.
The readonly keyword is different from the const keyword. A const field can only be initialized at the declaration of the field. A readonly field can be assigned multiple times in the field declaration and in any constructor. Therefore, readonly fields can have different values depending on the constructor used. Also, while a const field is a compile-time constant, the readonly field can be used for run-time constants as in the following example:
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 */ >In the preceding example, if you use a statement like the following example:
p2.y = 66; // Erroryou get the compiler error message:
A readonly field cannot be assigned to (except in a constructor or a variable initializer)
Readonly instance members
You can also use the readonly modifier to declare that an instance member doesn’t modify the state of a struct.
public readonly double Sum()
In the case of a read/write property, you can add the readonly modifier to the get accessor. Some get accessors may perform a calculation and cache the result, rather than simply returning the value of a private field. Adding the readonly modifier to the get accessor guarantees that the get accessor doesn’t modify the internal state of the object by caching any result.
You can find more examples in the readonly instance members section of the Structure types article.
Ref readonly return example
The readonly modifier on a ref return indicates that the returned reference can’t be modified. The following example returns a reference to the origin. It uses the readonly modifier to indicate that callers can’t modify the origin:
private static readonly SamplePoint s_origin = new SamplePoint(0, 0, 0); public static ref readonly SamplePoint Origin => ref s_origin;The type returned doesn’t need to be a readonly struct . Any type that can be returned by ref can be returned by ref readonly .
Readonly ref readonly return example
A ref readonly return can also be used with readonly instance members on struct types:
public struct ReadonlyRefReadonlyExample < private int _data; public readonly ref readonly int ReadonlyRefReadonly(ref int reference) < // _data = 1; // Compile error if uncommented. return ref reference; >>The method essentially returns a readonly reference together with the instance member (in this case a method) being readonly (not able to modify any instance fields).
C# language specification
For more information, see the C# Language Specification. The language specification is the definitive source for C# syntax and usage.
You can also see the language specification proposals:
- readonly ref and readonly struct
- readonly struct members
See also
- Add readonly modifier (style rule IDE0044)
- C# Reference
- C# Programming Guide
- C# Keywords
- Modifiers
- const
- Fields
Collaborate with us on GitHub
The source for this content can be found on GitHub, where you can also create and review issues and pull requests. For more information, see our contributor guide.
ReadOnly (Visual Basic)
Указывает, что переменная или свойство могут быть прочитаны, но не записаны.
Комментарии
Правила
- Контекст объявления. ReadOnly можно использовать только на уровне модуля. Это означает, что контекст объявления для ReadOnly элемента должен быть классом, структурой или модулем и не может быть исходным файлом, пространством имен или процедурой.
- Комбинированные модификаторы. Нельзя указать ReadOnly вместе с Static в одном объявлении.
- Назначение значения. Код, использующее свойство, ReadOnly не может задать его значение. Но код, имеющий доступ к базовому хранилищу, может назначить или изменить значение в любое время. Значение переменной ReadOnly можно присвоить только в ее объявлении или в конструкторе класса или структуры, в которой она определена.
Когда следует использовать переменную только для чтения
Существуют ситуации, в которых нельзя использовать оператор Const для объявления и назначения значения константы. Например, Const инструкция может не принимать тип данных, который требуется назначить, или вы не сможете вычислить значение во время компиляции с помощью константного выражения. Возможно, вы даже не знаете значение во время компиляции. В таких случаях можно использовать переменную ReadOnly для хранения значения константы.
Если тип данных переменной является ссылочным типом, например массивом или экземпляром класса, его члены могут быть изменены, даже если сама переменная имеет значение ReadOnly . Это показано в следующем примере.
ReadOnly characterArray() As Char = Sub ChangeArrayElement() characterArray(1) = "M"c End SubПри инициализации массив, на который characterArray() указывает , содержит «x», «y» и «z». Так как переменная characterArray имеет значение ReadOnly , ее значение нельзя изменить после ее инициализации, то есть нельзя назначить ей новый массив. Однако можно изменить значения одного или нескольких элементов массива. После вызова процедуры ChangeArrayElement массив, на который указывает characterArray() , содержит «x», «M» и «z».
Обратите внимание, что это похоже на объявление параметра процедуры byVal, что не позволяет процедуре изменять сам вызывающий аргумент, но позволяет ей изменять свои члены.
Пример
В следующем примере определяется ReadOnly свойство для даты найма сотрудника. Класс сохраняет значение свойства внутри как переменную Private , и только код внутри класса может изменить это значение. Однако свойство имеет значение Public , и любой код, который может получить доступ к классу, может считывать свойство .
Class employee ' Only code inside class employee can change the value of hireDateValue. Private hireDateValue As Date ' Any code that can access class employee can read property dateHired. Public ReadOnly Property dateHired() As Date Get Return hireDateValue End Get End Property End ClassМодификатор ReadOnly можно использовать в следующих контекстах:
См. также раздел
Совместная работа с нами на GitHub
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
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, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
Typescript. Свойства доступные только для чтения
В версии Typescript 2.0 был добавлен модификатор readonly . Свойствам помеченным модификатором readonly значение может быть присвоено только в момент инициализации, или в конструкторе того же класса. Любые другие присваивания значении запрещены.
Давайте посмотрим на пример. Здесь представлен простой тип Point , описываемый двумя свойствами, доступными только для чтения:
type Point = < readonly x: number; readonly y: number; >;Теперь мы можем создать объект представляющий собой начало координат, и инициализировать x и y со значением 0 :
const origin: Point = < x: 0, y: 0 >;Однако, так как свойства x и y помечены readonly , мы не можем изменить их значения впоследствии:
// Error: Left-hand side of assignment expression // cannot be a constant or read-only property origin.x = 100;Более реалистичный пример
Приведённый выше пример может показаться надуманным, давайте рассмотрим следующую функцию:
function moveX(point: Point, offset: number): Point
Функция moveX не должна изменять свойство x переданного объекта point . Компилятор TypeScript обязательно начнёт ругаться, если вы попробуете это сделать, так как свойство помечено модификатором readonly . Вместо этого moveX должна возвращать новый объект с изменёнными значениями:
function moveX(p: Point, offset: number): Point < return < x: p.x + offset, y: p.y >; >Теперь компилятор будет счастлив, больше нет попыток присвоить значения свойствам помеченным readonly . Мы создали новый объект, который инициализируется с обновлёнными значениями.
Свойства класса, доступные только для чтения
Вы также можете применять модификатор readonly к свойствам описанным в классе. Здесь представлен класс Circle с readonly полем radius и и свойством area , которое косвенным образом реализует доступность только для чтения, потому что не имеет сеттера:
class Circle < readonly radius: number; constructor(radius: number) < this.radius = radius; >get area() < return Math.PI * this.radius ** 2; >>Обратите вниманием, что area вычисляется с помощью оператора возведения в степень. И radius , и area доступны извне класса для чтения, потому что ни один не помечен как private , но не для записи:
const unitCircle = new Circle(1); unitCircle.radius; // 1 unitCircle.area; // 3.141592653589793 // Error: Left-hand side of assignment expression // cannot be a constant or read-only property unitCircle.radius = 42; // Error: Left-hand side of assignment expression // cannot be a constant or read-only property unitCircle.area = 42;Доступные только для чтения поля интерфейсов
Поля интерфейсов также могут помечены, как доступные только для чтения. Например, тип ReadOnlyArray предотвращает запись значений в описанные свойства:
interface ReadonlyArray < readonly length: number; // . readonly [n: number]: T; >Следующее присваивание будет невалидным:
const primesBelow10: ReadonlyArray = [2, 3, 5, 7]; // Error: Left-hand side of assignment expression // cannot be a constant or read-only property primesBelow10[4] = 11;readonly vs иммутабельность
Модификатор readonly — это часть системы типов TypeScript . Он используется только компилятором для проверки незаконных присваивании значений. Как только TypeScript код компилируется в JavaScript такое понятие, как readonly уходит прочь. Не поленитесь поиграть с маленьким примером, чтобы посмотреть во что компилируются свойства доступные только для чтения.
Так как модификатор readonly — это только артефакт при компиляции, он не является защитой от присваивания значений во время исполнения кода. Тем не менее это ещё одна особенность TypeScript , которая поможет вам писать правильный код, оставив компилятору работу по проверке непреднамеренных присвоений значений.
- Веб-разработка
- JavaScript
- TypeScript