Compartir a través de


readonly (Referencia de C#)

La readonly palabra clave es un modificador que se puede usar en cinco contextos:

  • En una declaración de campo, readonly indica que la asignación al campo solo puede producirse como parte de la declaración o en un constructor de la misma clase. Un campo de solo lectura se puede asignar y reasignar varias veces dentro de la declaración de campo y el constructor.

    No se puede asignar un readonly campo después de que se cierre el constructor. Esta regla tiene diferentes implicaciones para los tipos de valor y los tipos de referencia:

    • Dado que los tipos de valor contienen directamente sus datos, un campo que es un readonly tipo de valor es inmutable.
    • Dado que los tipos de referencia contienen una referencia a sus datos, un campo que es un readonly tipo de referencia siempre debe hacer referencia al mismo objeto. Es posible que ese objeto no sea inmutable. El readonly modificador impide reemplazar el valor de campo por una instancia diferente del tipo de referencia. Sin embargo, el modificador no impide que los datos de instancia del campo se modifiquen a través del campo de solo lectura.

    Advertencia

    Un tipo visible externamente que contiene un campo de solo lectura visible externamente que es un tipo de referencia mutable puede ser una vulnerabilidad de seguridad y puede desencadenar la advertencia CA2104 : "No declarar tipos de referencia mutables de solo lectura".

  • En una readonly struct definición de tipo, readonly indica que el tipo de estructura es inmutable. Para obtener más información, consulte la readonly sección struct del artículo Tipos de estructura .

  • En una declaración de miembro de instancia dentro de un tipo de estructura, readonly indica que un miembro de instancia no modifica el estado de la estructura. Para obtener más información, consulte la readonly sección miembros de instancia del artículo Tipos de estructura .

  • En un ref readonly retorno de método, el modificador readonly indica que el método devuelve una referencia y que no se permiten escrituras a esa referencia.

Ejemplo de campo de solo lectura

En este ejemplo, el valor del campo year no se puede cambiar en el método ChangeYear, aunque se le asignó un valor en el constructor de clase:

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

Puede asignar un valor a un readonly campo solo en los contextos siguientes:

  • Cuando la variable se inicializa en la declaración, por ejemplo:

    public readonly int y = 5;
    
  • En un constructor de instancia de la clase que contiene la declaración de campo de instancia.

  • En el constructor estático de la clase que contiene la declaración de campo estático.

Estos contextos de constructor también son los únicos contextos en los que es válido pasar un readonly campo como parámetro out o ref .

Nota:

La readonly palabra clave es diferente de la palabra clave const . Un const campo solo se puede inicializar en la declaración del campo. Un readonly campo se puede asignar varias veces en la declaración de campo y en cualquier constructor. Por lo tanto, los readonly campos pueden tener valores diferentes en función del constructor usado. Además, mientras un const campo es una constante en tiempo de compilación, el readonly campo se puede usar para constantes en tiempo de ejecución como en el ejemplo siguiente:

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

En el ejemplo anterior, si usa una instrucción como en el ejemplo siguiente:

p2.y = 66;        // Error

Recibe el mensaje de error del compilador:

No se puede asignar un campo de solo lectura a (excepto en un constructor o un inicializador de variable).

Miembros de instancia readonly

También puede usar el modificador readonly para declarar que un miembro de instancia no modifica el estado de una estructura.

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

Nota:

En el caso de una propiedad de lectura y escritura, puede agregar el modificador readonly al accesor get. Algunos get descriptores de acceso pueden realizar un cálculo y almacenar en caché el resultado, en lugar de simplemente devolver el valor de un campo privado. Agregar el modificador readonly al descriptor de acceso get garantiza que el descriptor de acceso get no modifique el estado interno del objeto mediante la caché de ningún resultado.

Puede encontrar más ejemplos en la sección miembros de instanciareadonly del artículo Tipos de estructura.

Ejemplo de devolución de referencia de solo lectura

El modificador readonly en un ref return indica que no se puede modificar la referencia devuelta. En el ejemplo siguiente se devuelve una referencia al origen. Usa el readonly modificador para indicar que los autores de llamadas no pueden modificar el origen:

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

El tipo devuelto no necesita ser un readonly struct. Cualquier tipo que pueda devolverse mediante ref puede devolverse mediante ref readonly.

Ejemplo de devolución readonly ref readonly

También ref readonly return se puede usar con readonly miembros de instancia en 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;
    }
}

Básicamente, el método devuelve una referencia readonly junto con el miembro de instancia (en este caso, un método) que readonly no puede modificar ningún campo de instancia.

Especificación del lenguaje C#

Para obtener más información, consulte la Especificación del lenguaje C#. La especificación del lenguaje es el origen definitivo de la sintaxis y el uso de C#.

También puede ver las propuestas de especificación del lenguaje:

Consulte también