¿Cuál es la diferencia entre constante y solo lectura en C#?

Resuelto readonly asked hace 15 años • 30 respuestas

¿Cuál es la diferencia entre consty readonlyen C#?

¿Cuándo usarías uno sobre el otro?

readonly avatar Sep 11 '08 15:09 readonly
Aceptado

Aparte de la aparente diferencia de

  • tener que declarar el valor en el momento de una definición para los valores constVS readonlyse puede calcular dinámicamente, pero debe asignarse antes de que salga el constructor. Después de eso se congela.
  • constson implícitamente static. Utiliza una ClassName.ConstantNamenotación para acceder a ellos.

Hay una diferencia sutil. Considere una clase definida en AssemblyA.

public class Const_V_Readonly
{
  public const int I_CONST_VALUE = 2;
  public readonly int I_RO_VALUE;
  public Const_V_Readonly()
  {
     I_RO_VALUE = 3;
  }
}

AssemblyBhace referencia AssemblyAy utiliza estos valores en el código. Cuando esto se compila:

  • en el caso del constvalor, es como un buscar-reemplazar. El valor 2 está "integrado" en el AssemblyBIL. Esto significa que si mañana actualizo I_CONST_VALUEa 20, AssemblyBtodavía tendré 2 hasta que lo vuelva a compilar .
  • en el caso del readonlyvalor, es como refuna ubicación de memoria. El valor no está integrado en AssemblyBel IL de . Esto significa que si se actualiza la ubicación de la memoria, AssemblyBse obtiene el nuevo valor sin necesidad de volver a compilarlo. Entonces, si I_RO_VALUEse actualiza a 30, solo necesita compilar AssemblyAy no es necesario volver a compilar todos los clientes.

Entonces, si está seguro de que el valor de la constante no cambiará, utilice un const.

public const int CM_IN_A_METER = 100;

Pero si tiene una constante que puede cambiar (precisión de egwrt) o en caso de duda, utilice un archivo readonly.

public readonly float PI = 3.14;

Actualización: Aku necesita una mención porque él lo señaló primero. También necesito mencionar dónde aprendí esto: C# efectivo - Bill Wagner

Gishu avatar Sep 11 '2008 08:09 Gishu

¡Hay un problema con las constantes! Si hace referencia a una constante de otro ensamblado, su valor se compilará directamente en el ensamblado que llama. De esa manera, cuando actualice la constante en el ensamblado al que se hace referencia, ¡no cambiará en el ensamblado que llama!

aku avatar Sep 11 '2008 08:09 aku

Constantes

  • Las constantes son estáticas por defecto
  • Deben tener un valor en el momento de la compilación (puede tener, por ejemplo, 3.14 * 2, pero no puede llamar a métodos)
  • Podría declararse dentro de funciones
  • Se copian en cada ensamblado que los utiliza (cada ensamblado obtiene una copia local de los valores)
  • Se puede utilizar en atributos.

Campos de instancia de solo lectura

  • Debe tener un valor establecido, cuando el constructor salga
  • Se evalúan cuando se crea la instancia.

Campos estáticos de solo lectura

  • Se evalúan cuando la ejecución del código llega a la referencia de clase (cuando se crea una nueva instancia o se ejecuta un método estático)
  • Debe tener un valor evaluado cuando finalice el constructor estático.
  • No se recomienda poner ThreadStaticAttribute en estos (los constructores estáticos se ejecutarán en un solo subproceso y establecerán el valor para su subproceso; todos los demás subprocesos tendrán este valor sin inicializar)
 avatar Dec 02 '2008 11:12

Solo para agregar, readonlypara los tipos de referencia solo hace que la referencia solo lea, no los valores. Por ejemplo:

public class Const_V_Readonly
{
  public const int I_CONST_VALUE = 2;
  public readonly char[] I_RO_VALUE = new Char[]{'a', 'b', 'c'};

  public UpdateReadonly()
  {
     I_RO_VALUE[0] = 'V'; //perfectly legal and will update the value
     I_RO_VALUE = new char[]{'V'}; //will cause compiler error
  }
}
 avatar Sep 11 '2008 10:09