Поделиться через


readonly (справочник по C#)

Используйте ключевое readonly слово в качестве модификатора в пяти контекстах:

  • В объявлении поля означает, readonly что поле можно назначить только во время объявления или конструктора в том же классе. Можно назначить и переназначить поле чтения несколько раз в объявлении поля и конструкторе.

    После завершения конструктора нельзя назначить readonly поле. Это правило влияет на типы значений и ссылочные типы по-разному:

    • Так как типы значений непосредственно содержат их данные, поле, которое является типом readonly значения, является неизменяемым.
    • Так как ссылочные типы содержат ссылку на их данные, поле, которое является ссылочным типом readonly , всегда должно ссылаться на один и тот же объект. Этот объект может быть неизменяемым. Модификатор readonly предотвращает замену значения поля другим экземпляром ссылочного типа. Однако модификатор не предотвращает изменение данных экземпляра поля через поле, доступное только для чтения.

    Предупреждение

    Внешний видимый тип, содержащий внешне видимое поле только для чтения, которое является изменяемым ссылочным типом, может быть уязвимостью системы безопасности и может вызвать предупреждение CA2104 : "Не объявлять только изменяемые типы ссылок".

  • В определении readonly struct типа означает, readonly что тип структуры неизменяем. Дополнительные сведения см. в readonly разделе структуры статьи "Типы структур ".

  • В объявлении члена экземпляра в типе структуры означает, readonly что член экземпляра не изменяет состояние структуры. Дополнительные сведения см. в readonly разделе "Члены экземпляра " статьи "Типы структур ".

  • В возвращаемом методеref readonly модификатор указывает, readonly что метод возвращает ссылку и записи не допускается для этой ссылки.

Справочные документы по языку C# описывают последнюю выпущенную версию языка C#. Она также содержит начальную документацию по функциям в общедоступных предварительных версиях для предстоящего языкового выпуска.

Документация определяет любую функцию, впервые представленную в последних трех версиях языка или в текущих общедоступных предварительных версиях.

Подсказка

Чтобы узнать, когда функция впервые появилась в C#, ознакомьтесь со статьей об истории версий языка C#.

Пример поля 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={p1.x}, y={p1.y}, z={p1.z}");
        SamplePoint p2 = new SamplePoint();
        p2.x = 55;   // OK
        Console.WriteLine($"p2: x={p2.x}, y={p2.y}, z={p2.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()
{
    return X + Y;
}

Замечание

Для свойства чтения и записи можно добавить readonly модификатор в get метод доступа. Некоторые get методы доступа выполняют вычисление и кэшируют результат, а не просто возвращают значение частного поля. readonly Добавив модификатор get к методу доступа, вы гарантируете, что get метод доступа не изменяет внутреннее состояние объекта путем кэширования любого результата.

Дополнительные примеры см. в readonly разделе "Члены экземпляра " статьи "Типы структур ".

Пример возврата ссылки только для чтения

Модификатор readonly для a 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 ref возвращаемого значения readonly

Вы также можете использовать ref readonly return элементы экземпляра для readonlystruct типов:

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#.

См. также