readonly (Referencia de C#)
La palabra clave readonly es un modificador que se puede usar en cuatro contextos:
En una declaración de campo,
readonlyindica que la asignación a un campo solo se puede producir como parte de la declaración o en un constructor de la misma clase. Se puede asignar y reasignar varias veces un campo de solo lectura dentro de la declaración de campo y el constructor.No se puede asignar un campo
readonlydespués de que el constructor salga. Esta regla tiene diferentes implicaciones para los tipos de valor y tipos de referencia:- Debido a que los tipos de valor contienen directamente sus datos, un campo que es un tipo de valor
readonlyes inmutable. - Dado que los tipos de referencia contienen una referencia a sus datos, un campo que es un tipo de referencia
readonlydebe referirse siempre al mismo objeto. Ese objeto no es inmutable. El modificadorreadonlyevita que el campo se reemplace 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 contenga un campo de solo lectura visible externamente que sea un tipo de referencia mutable puede ser una vulnerabilidad de seguridad y puede desencadenar la advertencia CA2104: "No declarar tipos de referencias mutables de solo lectura".
- Debido a que los tipos de valor contienen directamente sus datos, un campo que es un tipo de valor
En una definición de tipo de
readonly struct,readonlyindica que el tipo de estructura es inmutable. Para obtener más información, vea la sección structreadonlydel artículo tipos de estructura.En una declaración de miembro de instancia dentro de un tipo de estructura,
readonlyindica que un miembro de instancia no modifica el estado de la estructura. Para obtener más información, vea la sección Miembros de instanciareadonlydel artículo Tipos de estructura.En una devolución del método
ref readonly, el modificadorreadonlyindica que el método devuelve una referencia y las operaciones de escritura no se permiten en esa referencia.
Los contextos readonly struct y ref readonly se han agregado en C# 7.2. Los miembros de estructura readonly se han agregado en C# 8.0.
Ejemplo de campo readonly
En este ejemplo, el valor del campo year no se puede cambiar en el método ChangeYear, aunque se asigne 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.
}
}
Solo se puede asignar un valor a un campo readonly en los siguientes contextos:
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 son también los únicos en los que es válido pasar un campo readonly como parámetro out o ref.
Nota
La palabra clave readonly es diferente de la palabra clave const. Un campo const solo se puede inicializar en la declaración del campo. Un campo readonly se puede asignar varias veces en la declaración de campo y en cualquier constructor. Por lo tanto, los campos readonly pueden tener diferentes valores en función del constructor que se use. Además, mientras que un campo const es una constante en tiempo de compilación, el campo readonly puede usarse para constantes en tiempo de ejecución, como muestra el siguiente ejemplo:
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 se usa una instrucción como el ejemplo siguiente:
p2.y = 66; // Error
se obtendrá el siguiente mensaje de error del compilador:
No se puede asignar un campo de solo lectura (excepto en un constructor o inicializador de variable) .
Ejemplo de devolución de Ref readonly
El modificador readonly en un elemento ref return indica que la referencia devuelta no se puede modificar. En el ejemplo siguiente se devuelve una referencia al origen. Usa el modificador readonly para indicar que los autores de la llamada 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;
No es necesario que el tipo devuelto sea una readonly struct. Cualquier tipo que pueda devolver ref también puede devolver ref readonly.
Especificación del lenguaje C#
Para obtener más información, consulte la Especificación del lenguaje C#. La especificación del lenguaje es la fuente definitiva de la sintaxis y el uso de C#.
También puede ver las propuestas de especificación del lenguaje: