referencia propiedad modificador metodo codigos c# readonly

propiedad - static c#



¿Cuáles son los beneficios de marcar un campo como `readonly` en C#? (14)

¿Cuáles son los beneficios de tener una variable miembro declarada como de solo lectura? ¿Es solo proteger contra alguien que cambia durante el ciclo de vida de la clase o hay mejoras en la velocidad del compilador debido a esta palabra clave?


Existe un caso potencial en el que el compilador puede realizar una optimización del rendimiento en función de la presencia de la palabra clave de solo lectura.

Esto solo se aplica si el campo de solo lectura también está marcado como estático . En ese caso, el compilador JIT puede asumir que este campo estático nunca cambiará. El compilador JIT puede tener esto en cuenta al compilar los métodos de la clase.

Ejemplo típico: su clase podría tener un campo IsDebugLoggingEnabled de solo lectura estático que se inicializa en el constructor (por ejemplo, basado en un archivo de configuración). Una vez que los métodos reales son compilados JIT, el compilador puede omitir partes enteras del código cuando el registro de depuración no está habilitado.

No he comprobado si esta optimización se implementa realmente en la versión actual del compilador JIT, por lo que esto es sólo una especulación.


La palabra clave readonly se usa para declarar constante una variable miembro, pero permite que el valor se calcule en tiempo de ejecución. Esto difiere de una constante declarada con el modificador const , que debe tener su valor establecido en tiempo de compilación. Usando readonly puede establecer el valor del campo en la declaración o en el constructor del objeto del que el campo es miembro.

Úselo también si no desea tener que volver a compilar archivos DLL externos que hacen referencia a la constante (ya que se reemplaza en el momento de la compilación).


No creo que haya ningún aumento de rendimiento al usar un campo de solo lectura. Es simplemente una verificación para asegurarse de que una vez que el objeto esté completamente construido, ese campo no pueda apuntar a un nuevo valor.

Sin embargo, "readonly" es muy diferente de otros tipos de semántica de solo lectura porque el CLR lo aplica en tiempo de ejecución. La palabra clave readonly compila hasta .initonly que es verificable por el CLR.

La verdadera ventaja de esta palabra clave es generar estructuras de datos inmutables. Las estructuras de datos inmutables, por definición, no se pueden cambiar una vez construidas. Esto hace que sea muy fácil razonar sobre el comportamiento de una estructura en tiempo de ejecución. Por ejemplo, no hay peligro de pasar una estructura inmutable a otra porción aleatoria de código. No pueden cambiarlo nunca, así que puedes programar de manera confiable contra esa estructura.

Aquí hay una buena entrada sobre uno de los beneficios de la inmutabilidad:


No hay beneficios aparentes de rendimiento en el uso de readonly , al menos ninguno que haya visto mencionado en ninguna parte. Es solo por hacer exactamente lo que sugiere, para evitar modificaciones una vez que se haya inicializado.

Por lo tanto, es beneficioso porque le ayuda a escribir código más robusto y más legible. El beneficio real de este tipo de cosas viene cuando trabajas en equipo o para mantenimiento. Declarar algo como readonly es similar a poner un contrato para el uso de esa variable en el código. Piensa que es como agregar documentación de la misma forma que otras palabras clave como internal o private , estás diciendo que "esta variable no debe modificarse después de la inicialización", y además la estás aplicando .

Por lo tanto, si crea una clase y marca algunas variables de miembro readonly por diseño, evitará que usted u otro miembro del equipo cometa un error más adelante cuando amplíen o modifiquen su clase. En mi opinión, ese es un beneficio que vale la pena (a costa de la complejidad adicional del lenguaje, como lo mencionan en los comentarios).


No olvide que hay una solución alternativa para obtener los campos de readonly establecidos fuera de cualquier constructor utilizando parámetros.

Un poco desordenado pero

private readonly int _someNumber; private readonly string _someText; public MyClass(int someNumber) : this(data, null) { } public MyClass(int someNumber, string someText) { Initialise(out _someNumber, someNumber, out _someText, someText); } private void Initialise(out int _someNumber, int someNumber, out string _someText, string someText) { //some logic }

Más discusión aquí: http://www.adamjamesnaylor.com/2013/01/23/Setting-Readonly-Fields-From-Chained-Constructors.aspx


Otra parte interesante del uso del marcado de solo lectura puede ser proteger el campo de la inicialización en singleton.

por ejemplo en el código de csharpindepth :

public sealed class Singleton { private static readonly Lazy<Singleton> lazy = new Lazy<Singleton>(() => new Singleton()); public static Singleton Instance { get { return lazy.Value; } } private Singleton() { } }

readonly juega un pequeño papel en la protección del campo Singleton para que no se inicialice dos veces. Otro detalle es que para el escenario mencionado no se puede usar const porque const obliga la creación durante el tiempo de compilación, pero singleton hace la creación en tiempo de ejecución.


Para ponerlo en términos muy prácticos:

Si usa una constante en las referencias dll A y dll B que const, el valor de esa constante se compilará en la dll B. Si vuelve a desplegar la dll A con un nuevo valor para esa const, la dll B seguirá usando el valor original.

Si usa readonly en las referencias dll A y dll B que readonly, esa lectura solo se buscará en tiempo de ejecución. Esto significa que si vuelve a implementar la dll A con un nuevo valor para esa solo lectura, la dll B usará ese nuevo valor.


Puede haber un beneficio de rendimiento en WPF, ya que elimina la necesidad de propiedades de dependencia caras. Esto puede ser especialmente útil con colecciones.


Si tiene un valor predefinido o precalculado que debe permanecer igual en todo el programa, entonces debe usar una constante, pero si tiene un valor que debe proporcionarse en el tiempo de ejecución, pero una vez asignado, debe permanecer igual en todo el programa. solo lectura. por ejemplo, si tiene que asignar la hora de inicio del programa o si tiene que almacenar un valor provisto por el usuario en la inicialización del objeto y tiene que restringirlo de cambios adicionales, debe usar readonly.



Tenga cuidado con los arreglos privados de solo lectura. Si se expone a un cliente como un objeto (puede hacer esto para la interoperabilidad COM como lo hice), el cliente puede manipular los valores de la matriz. Utilice el método Clone () cuando devuelva una matriz como un objeto.


Tenga en cuenta que readonly solo se aplica al valor en sí mismo, por lo tanto, si está utilizando un tipo de referencia, readonly solo protege a la referencia de cambios. El estado de la instancia no está protegido por readonly.


readonly puede inicializarse en la declaración u obtener su valor solo del constructor. A diferencia de const , tiene que ser inicializado y declarado al mismo tiempo. readonly tiene todo lo que tiene const , más la inicialización del constructor

código https://repl.it/HvRU/1

using System; class MainClass { public static void Main (string[] args) { Console.WriteLine(new Test().c); Console.WriteLine(new Test("Constructor").c); Console.WriteLine(new Test().ChangeC()); //Error A readonly field // `MainClass.Test.c'' cannot be assigned to (except in a constructor or a // variable initializer) } public class Test { public readonly string c = "Hello World"; public Test() { } public Test(string val) { c = val; } public string ChangeC() { c = "Method"; return c ; } } }


Añadiendo un aspecto básico para responder esta pregunta:

Las propiedades se pueden expresar como de solo lectura al excluir al operador set . Por lo tanto, en la mayoría de los casos no necesitará agregar la palabra clave de readonly a las propiedades:

public int Foo { get; } // a readonly property

En contraste con eso: los campos necesitan la palabra clave de readonly para lograr un efecto similar:

public readonly int Foo; // a readonly field

Por lo tanto, uno de los beneficios de marcar un campo como readonly puede ser lograr un nivel de protección contra escritura similar al de una propiedad sin set operador, sin tener que cambiar el campo a una propiedad, si por alguna razón se desea.