Estática solo lectura vs const


He leído acerca de los campos const y static readonly. Tenemos algunas clases que contienen solo valores constantes. Utilizado para varias cosas alrededor en nuestro sistema. Así que me pregunto si mi observación es correcta:

¿Este tipo de valores constantes siempre deben ser static readonly para todo lo que es público? ¿Y solo usar const para valores internos / protegidos / privados?

¿Qué recomienda? ¿Debería tal vez no usar los campos static readonly, sino usar propiedades tal vez?

 1219
Author: John Saunders, 2009-04-16

15 answers

public static readonly los campos son un poco inusuales; las propiedades public static (con solo un get) serían más comunes (quizás respaldadas por un campo private static readonly).

const los valores se queman directamente en el sitio de llamada; esto es de doble filo:

  • es inútil si el valor se obtiene en tiempo de ejecución, tal vez desde config
  • si cambia el valor de una const, debe reconstruir todos los clientes
  • pero puede ser más rápido, ya que evita una llamada a un método...
  • ...que a veces podría han sido insertados por el JIT de todos modos

Si el valor nunca cambia, entonces const está bien - Zero etc. haga conss razonables ;p Aparte de eso, static las propiedades son más comunes.

 841
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-24 04:58:30

Usaría static readonlysi el Consumidor está en un ensamblaje diferente. Tener al const y al Consumidor en dos conjuntos diferentes es una buena manera de dispararse en el pie.

 206
Author: Michael Stum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-25 16:50:58

Algunas otras cosas

Const int a

  • debe inicializarse
  • la inicialización debe ser en tiempo de compilación

Readonly int a

  • puede usar el valor predeterminado, sin inicializar
  • la inicialización puede ser en tiempo de ejecución
 176
Author: Peter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-10 17:04:12

Esto es solo un suplemento a las otras respuestas. No voy a repetirlas (ahora cuatro años después).

Hay situaciones donde un const y un non-const tienen semántica diferente. Por ejemplo:

const int y = 42;

static void Main()
{
  short x = 42;
  Console.WriteLine(x.Equals(y));
}

Imprime True, mientras que:

static readonly int y = 42;

static void Main()
{
  short x = 42;
  Console.WriteLine(x.Equals(y));
}

Escribe False.

La razón es que el método x.Equals tiene dos sobrecargas, que tiene en un short (System.Int16) y uno que toma un object (System.Object). Ahora la pregunta es si uno o ambos se aplican con mi y argumento.

Cuando y es una constante en tiempo de compilación (literal), el caso const, es importante que exista una conversión implícita de int to short siempre que int sea una constante, y siempre que el compilador de C# verifique que su valor está dentro del rango de a short (que 42 está). Consulte Conversiones de expresiones constantes implícitas en la Especificación del Lenguaje C#. Así que ambas sobrecargas tienen que ser consideradas. Sobrecarga se prefiere Equals(short) (cualquier short es un object, pero no todos object son short). Así que y se convierte a short, y se usa esa sobrecarga. Entonces Equals compara dos short de valor idéntico, y eso da true.

Cuando y no es una constante, no existe conversión implícita de int a short. Eso es porque en general un int puede ser demasiado grande para caber en un short. (Existe una conversión explícita, pero no dije Equals((short)y), así que eso no es relevante.) Vemos que solo se aplica una sobrecarga, la Equals(object). Así que y está en caja con object. Entonces Equals va a comparar a System.Int16 con a System.Int32, y dado que los tipos de tiempo de ejecución ni siquiera están de acuerdo, eso producirá false.

Concluimos que en algunos casos (raros), cambiar un miembro de tipo const a un campo static readonly (o de otra manera, cuando eso es posible) puede cambiar el comportamiento del programa.

 157
Author: Jeppe Stig Nielsen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-13 13:30:01

Una cosa a tener en cuenta es const está restringido a tipos primitivos / de valor (la excepción son las cadenas)

 83
Author: Chris S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-16 11:28:51

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 inicializar en la declaración o en un constructor. Por lo tanto, los campos readonly pueden tener diferentes valores dependiendo del constructor utilizado. Además, mientras que un campo const es una constante en tiempo de compilación, el campo readonly se puede usar para constantes de tiempo de ejecución

Referencia MSDN corta y clara aquí

 23
Author: yazanpro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-14 18:58:37

Solo Lectura estática : El valor se puede cambiar a través del constructor static en tiempo de ejecución. Pero no a través de la Función miembro.

Constante : Por defecto static. El valor no se puede cambiar desde ningún lugar (Ctor, Función, tiempo de ejecución, etc.).

Solo lectura : El valor se puede cambiar a través del constructor en tiempo de ejecución. Pero no a través de la Función miembro.

Puedes echar un vistazo a mi repositorio : Tipos de propiedad C# .

 17
Author: Yeasin Abedin Siam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-24 04:59:23

const y readonly son similares, pero no son exactamente lo mismo.

Un campo const es una constante en tiempo de compilación, lo que significa que ese valor se puede calcular en tiempo de compilación. Un campo readonly habilita escenarios adicionales en los que se debe ejecutar algún código durante la construcción del tipo. Después de la construcción, un campo readonly no se puede cambiar.

Por ejemplo, const los miembros se pueden usar para definir miembros como:

struct Test
{
    public const double Pi = 3.14;
    public const int Zero = 0;
}

Ya que valores como 3.14 y 0 son constantes en tiempo de compilación. Sin embargo, considere el caso en el que define un tipo y desea proporcionar algunas instancias prefabricadas del mismo. Por ejemplo, es posible que desee definir una clase de color y proporcionar "constantes"para colores comunes como Negro, Blanco, etc. No es posible hacer esto con miembros const, ya que los lados de la mano derecha no son constantes en tiempo de compilación. Uno podría hacer esto con miembros estáticos regulares:

public class Color
{
    public static Color Black = new Color(0, 0, 0);
    public static Color White = new Color(255, 255, 255);
    public static Color Red   = new Color(255, 0, 0);
    public static Color Green = new Color(0, 255, 0);
    public static Color Blue  = new Color(0, 0, 255);
    private byte red, green, blue;

    public Color(byte r, byte g, byte b) => (red, green, blue) = (r, g, b);
}

Pero entonces no hay nada para evitar que un cliente de Color se meta con él, tal vez intercambiando el Blanco y Negro valor. No hace falta decir que esto causaría consternación para otros clientes de la clase Color. La función "readonly" aborda este escenario.

Simplemente introduciendo la palabra clave readonly en las declaraciones, preservamos la inicialización flexible mientras evitamos que el código del cliente se escurra.

public class Color
{
    public static readonly Color Black = new Color(0, 0, 0);
    public static readonly Color White = new Color(255, 255, 255);
    public static readonly Color Red   = new Color(255, 0, 0);
    public static readonly Color Green = new Color(0, 255, 0);
    public static readonly Color Blue  = new Color(0, 0, 255);
    private byte red, green, blue;

    public Color(byte r, byte g, byte b) => (red, green, blue) = (r, g, b);
}

Es interesante notar que los miembros const son siempre estáticos, mientras que un miembro readonly puede ser estático o no, al igual que un campo regular.

Es es posible usar una sola palabra clave para estos dos propósitos, pero esto conduce a problemas de versiones o problemas de rendimiento. Supongamos por un momento que usamos una sola palabra clave para esto (const) y un desarrollador escribió:

public class A
{
    public static const C = 0;
}

Y un desarrollador diferente escribió código que se basó en A:

public class B
{
    static void Main() => Console.WriteLine(A.C);
}

Ahora, ¿puede el código que se genera confiar en el hecho de que A. C es una constante en tiempo de compilación? Es decir, ¿se puede simplemente sustituir el uso de A.c. por el valor 0? Si dices " sí " a esto, entonces eso significa que el desarrollador de A no puede cambiar la forma en que A. C se inicializa this esto ata las manos del desarrollador de A sin permiso.

Si dice "no" a esta pregunta, entonces se pierde una optimización importante. Tal vez el autor de A es positivo que A. C siempre será cero. El uso de const y readonly permite al desarrollador de A especificar la intent. Esto permite un mejor comportamiento de control de versiones y también un mejor rendimiento.

 13
Author: Ramesh Rajendran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-24 05:01:48

Mi preferencia es usar const siempre que pueda, que como se mencionó anteriormente se limita a expresiones literales o algo que no requiere evaluación.

Si me caliento contra esa limitación, entonces recurro a estática readonly, con una advertencia. Generalmente usaría una propiedad estática pública con un getter y un campo de backing private static readonly como Marc menciona aquí.

 11
Author: Peter Meyer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:26

Un campo estático de solo lectura es ventajoso cuando se expone a otros ensamblados un valor que podría cambiar en una versión posterior.

Por ejemplo, supongamos que assembly X expone una constante de la siguiente manera:

public const decimal ProgramVersion = 2.3;

Si assembly Y hace referencia a X y usa esta constante, el valor 2.3 se horneará en assembly Y cuando se compile. Esto significa que si X se recompila posteriormente con la constante establecida en 2.4, Y seguirá utilice el valor antiguo de 2.3 hasta que se recompile Y. Un estática el campo readonly evita este problema.

Otra forma de ver esto es que cualquier valor que pudiera el cambio en el futuro no es constante por definición, y por lo tanto debe no ser representado como tal.

 6
Author: Yagnesh Cangi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-07 13:44:22

Const: Const no es más que "constante", una variable cuyo valor es constante pero en tiempo de compilación. Y es obligatorio asignarle un valor. Por defecto, una const es estática y no podemos cambiar el valor de una variable const a lo largo de todo el programa.

Static ReadOnly: El valor de una variable de tipo Static Readonly puede asignarse en tiempo de ejecución o asignarse en tiempo de compilación y cambiarse en tiempo de ejecución. Pero el valor de esta variable solo se puede cambiar en el constructor estático. Y no se puede cambiar más. Puede cambiar solo una vez en tiempo de ejecución

Referencia: c-sharpcorner

 6
Author: mayank,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-24 11:30:26

Const:

  1. el valor debe darse en la declaración
  2. constante de tiempo de compilación

Readonly:

  1. el valor se puede dar en la declaración o durante el tiempo de ejecución usando constructores.El valor puede variar dependiendo del constructor utilizado.
  2. constante de tiempo de ejecución
 3
Author: dasumohan89,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-11 11:28:25

Hay una pequeña diferencia entre los campos const y static readonly en C#.Net

Const debe inicializarse con valor en tiempo de compilación.

Const es por defecto estático y necesita ser inicializado con un valor constante, que no se puede modificar más adelante. No se puede utilizar con todos los tipos de datos. Para ex-DateTime. No se puede utilizar con el tipo de datos DateTime.

public const DateTime dt = DateTime.Today;  //throws compilation error
public const string Name = string.Empty;    //throws compilation error
public static readonly string Name = string.Empty; //No error, legal

Readonly se puede declarar como estático, pero no es necesario. No es necesario inicializar en el momento de la declaración. Su valor se puede asignar o cambiar usando constructor una vez. Por lo tanto, existe la posibilidad de cambiar el valor del campo readonly una vez (no importa, si es estático o no), lo que no es posible con const.

 2
Author: Chirag,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-15 13:06:45

Las constantes son como su nombre indica, campos que no cambian y que normalmente se definen estáticamente en tiempo de compilación en el código.

Las variables de solo lectura son campos que pueden cambiar bajo condiciones específicas.

Pueden inicializarse cuando se declaran por primera vez como una constante, pero normalmente se inicializan durante la construcción de objetos dentro del constructor.

No se pueden cambiar después de la inicialización, en las condiciones mencionadas arriba.

Estática de solo lectura suena como una mala elección para mí, ya que, si es estática y nunca cambia, por lo que sólo tiene que utilizar const pública, si puede cambiar entonces no es una constante y luego, dependiendo de sus necesidades, puede utilizar solo lectura o simplemente una variable regular.

También, otra distinción importante es que una constante pertenece a la clase, mientras que la variable de solo lectura pertenece a la instancia!

 1
Author: Claudiu Cojocaru,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-21 22:49:32

Const: los valores de las variables const tienen que definirse junto con la declaración y después no cambiará. las const son implícitamente estáticas, por lo que sin crear una instancia de clase podemos acceder a ellas. esto tiene un valor en tiempo de compilación

ReadOnly : valores de variables de readonly que podemos definir tanto al declarar como al usar el constructor en tiempo de ejecución. las variables de solo lectura no pueden acceder sin instancia de clase.

Static readonly : static readonly los valores de las variables que podemos definir mientras declaramos, así como solo a través del constructor estático, pero no con cualquier otro constructor.estas variables también podemos acceder sin crear instancia de clase (como variables estáticas).

Static readonly será mejor opción si tenemos que consumir las variables en diferentes ensamblados.Por favor, compruebe los detalles completos en el siguiente enlace

Https://www.stum.de/2009/01/14/const-strings-a-very-convenient-way-to-shoot-yourself-in-the-foot/

 0
Author: user1756922,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-27 15:57:48