Partilhar via


somente leitura (referência C#)

A readonly palavra-chave é um modificador que pode ser usado em cinco contextos:

  • Em uma declaração de campo, readonly indica que a atribuição ao campo só pode ocorrer como parte da declaração ou em um construtor na mesma classe. Um campo somente leitura pode ser atribuído e reatribuído várias vezes dentro da declaração de campo e do construtor.

    Um readonly campo não pode ser atribuído após a saída do construtor. Esta regra tem diferentes implicações para tipos de valor e tipos de referência:

    • Como os tipos de valor contêm diretamente seus dados, um campo que é um tipo de readonly valor é imutável.
    • Como os tipos de referência contêm uma referência aos seus dados, um campo que é um tipo de readonly referência deve sempre referir-se ao mesmo objeto. Esse objeto pode não ser imutável. O readonly modificador impede a substituição do valor do campo por uma instância diferente do tipo de referência. No entanto, o modificador não impede que os dados da instância do campo sejam modificados por meio do campo somente leitura.

    Advertência

    Um tipo que é visível externamente e contém um campo visível externamente de leitura apenas, que é um tipo de referência mutável, pode ser uma vulnerabilidade de segurança e pode desencadear o aviso CA2104: "Não declare tipos de referência mutável como somente leitura."

  • Em uma definição de readonly struct tipo, readonly indica que o tipo de estrutura é imutável. Para obter mais informações, consulte a readonly seção struct do artigo Tipos de estrutura .

  • Em uma declaração de membro de instância dentro de um tipo de estrutura, readonly indica que um membro de instância não modifica o estado da estrutura. Para obter mais informações, consulte a readonly seção de membros da instância do artigo Tipos de estrutura .

  • Em um ref readonly retorno de método, o modificador indica que o readonly método retorna uma referência e as gravações não são permitidas para essa referência.

Exemplo de campo somente leitura

Neste exemplo, o valor do campo year não pode ser alterado no método ChangeYear, mesmo que tenha sido atribuído um valor no construtor da classe:

class Age
{
    private readonly int _year;
    Age(int year)
    {
        _year = year;
    }
    void ChangeYear()
    {
        //_year = 1967; // Compile error if uncommented.
    }
}

Você pode atribuir um valor a um readonly campo somente nos seguintes contextos:

  • Quando a variável é inicializada na declaração, por exemplo:

    public readonly int y = 5;
    
  • Em um construtor de instância da classe que contém a declaração de campo de instância.

  • No construtor estático da classe que contém a declaração de campo estático.

Esses contextos de construtor também são os únicos contextos em que é válido passar um readonly campo como um parâmetro out ou ref .

Observação

A readonly palavra-chave é diferente da palavra-chave const . Um campo const só pode ser inicializado na declaração do campo. Um readonly campo pode ser atribuído várias vezes na declaração de campo e em qualquer construtor. Portanto, readonly campos podem ter valores diferentes dependendo do construtor usado. Além disso, enquanto um const campo é uma constante de tempo de compilação, o readonly campo pode ser usado para constantes de tempo de execução, como no exemplo a seguir:

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
    */
}

No exemplo anterior, se utilizares uma declaração como o exemplo a seguir:

p2.y = 66;        // Error

Você recebe a mensagem de erro do compilador:

Um campo somente leitura não pode ser atribuído a (exceto em um construtor ou um inicializador de variável)

Membros de instância de apenas leitura

Você também pode usar o readonly modificador para declarar que um membro da instância não modifica o estado de uma struct.

public readonly double Sum()
{
    return X + Y;
}

Observação

No caso de uma propriedade de leitura/gravação, você pode adicionar o readonly modificador ao get acessador. Alguns get acessadores podem executar um cálculo e armazenar em cache o resultado, em vez de simplesmente retornar o valor de um campo privado. Adicionar o readonly modificador ao get acessador garante que o get acessador não modifique o estado interno do objeto armazenando em cache qualquer resultado.

Você pode encontrar mais exemplos na readonly seção de membros da instância do artigo Tipos de estrutura .

Exemplo de retorno somente leitura Ref

O readonly modificador em um ref return indica que a referência retornada não pode ser modificada. O exemplo a seguir retorna uma referência à origem. Ele usa o readonly modificador para indicar que os chamadores não podem modificar a origem:

private static readonly SamplePoint s_origin = new SamplePoint(0, 0, 0);
public static ref readonly SamplePoint Origin => ref s_origin;

O tipo retornado não precisa ser um readonly struct. Qualquer tipo que possa ser devolvido por ref pode ser devolvido por ref readonly.

Exemplo de retorno somente leitura ref readonly

A ref readonly return também pode ser usado com readonly membros de instância em struct tipos:

public struct ReadonlyRefReadonlyExample
{
    private int _data;

    public readonly ref readonly int ReadonlyRefReadonly(ref int reference)
    {
        // _data = 1; // Compile error if uncommented.
        return ref reference;
    }
}

O método essencialmente retorna uma readonly referência junto com o membro da instância (neste caso, um método) sendo readonly (não é capaz de modificar nenhum campo de instância).

Especificação da linguagem C#

Para obter mais informações, consulte a Especificação da Linguagem C# . A especificação da linguagem é a fonte definitiva para a sintaxe e o uso do C#.

Ver também