¿Hay alguna diferencia entre las variables privadas const y privadas de solo lectura en C #?

StackOverflow https://stackoverflow.com/questions/410723

  •  03-07-2019
  •  | 
  •  

Pregunta

¿Hay alguna diferencia entre tener una variable private const o una variable private static readonly en C # (aparte de tener que asignar la const una expresión en tiempo de compilación)?

Dado que ambos son privados, no hay enlaces con otras bibliotecas. Entonces, ¿haría alguna diferencia? ¿Puede hacer una diferencia de rendimiento, por ejemplo? Cuerdas pasadas? ¿Algo similar?

¿Fue útil?

Solución

Bueno, puedes usar consts en atributos, ya que existen como tiempo de compilación. No puede predecir el valor de una variable de solo lectura estática, ya que .cctor podría inicializarlo desde la configuración, etc.

En términos de uso, las constantes se queman en el código de llamada. Esto significa que si recompila una biblioteca dll para cambiar una constante pública , pero no cambia los consumidores, entonces los consumidores seguirán utilizando el valor original. Con una variable de solo lectura esto no sucederá. El cambio es que las constantes son (muy, muy ligeramente) más rápidas, ya que simplemente carga el valor (en lugar de tener que desreferenciarlo).

Re internado; aunque puede hacerlo manualmente, esta es comúnmente una característica de compilación / tiempo de ejecución de literales; si inicia un campo de solo lectura a través de un literal:

someField = "abc";

entonces el " abc " será internado. Si lo lees desde la configuración, no lo será. Debido a que una cadena constante debe ser literal, también será internada, pero se accede de manera diferente: nuevamente, la lectura desde el campo es una desreferencia, en lugar de un ldstr .

Otros consejos

De hecho, los dos tipos no se pueden cambiar después de que se inicializaron, pero existen algunas diferencias entre ellos:

  • 'const' debe inicializarse donde se declaran (en tiempo de compilación), mientras que 'readonly' puede inicializarse donde se declara o dentro del constructor (tiempo de ejecución).

Por ejemplo, const podría usarse en esta situación:

public class MathValues
{
  public const double PI = 3.14159;
}

Y solo lectura sería mejor para este caso:

public class Person
{
    public readonly DateTime birthDate;

    public Person(DateTime birthDate)
    {
        this.birthDate = birthDate;
    }
}

o

public class Person
{
    public readonly DateTime birthDate = new DateTime(1986, 1, 24);
}
  • 'const' es estático, por lo que se comparte entre todas las instancias de esa clase y se puede acceder directamente (como MathValues.PI), mientras que 'readonly' no es estático. Como consecuencia, una declaración como 'static const' es ilegal porque const es estática, pero 'static readonly' es legal

  • 'const' solo puede contener un tipo integral (sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool o string), una enumeración o un referencia a nulo (no clases o estructuras porque se inicializan en tiempo de ejecución, con la palabra clave 'nueva'), mientras que 'readonly' puede contener tipos, estructuras o clases complejas (utilizando la nueva palabra clave en la inicialización) pero no puede contener enumeraciones

Algo a tener en cuenta sobre las constantes es que en realidad están almacenadas en su ejecutable, por lo que declarar muchas de ellas aumentará el tamaño del archivo ejecutable.

Normalmente, este no es un gran problema, pero un amigo mío trabajó en una empresa que impuso un "todo debe ser constante" regla y logró aumentar significativamente su tamaño ejecutable compilado.

Aquí están las diferencias entre los campos C # .NET const , readonly y static readonly (de este artículo ).

Constantes :

  • Estática por defecto
  • Debe tener un valor de tiempo de compilación (es decir, puede tener '' A '' + '' B '' pero no puede tener llamadas a métodos)
  • Se puede usar en atributos
  • Se copian en cada ensamblaje que los usa (cada ensamblaje obtiene una copia local de valores)
  • Podría declararse dentro de las funciones

Campos de instancia de solo lectura :

  • Se evalúan cuando se crea la instancia
  • Debe tener un valor establecido antes de que el constructor salga

Campos de solo lectura estáticos :

  • Se evalúan cuando la ejecución del código alcanza la referencia de clase (es decir: se crea una nueva instancia o se ejecuta un método estático)
  • Debe haber evaluado el valor en el momento en que se realiza el constructor estático
  • Realmente no desea poner ThreadStaticAttribute en estos (ya que el constructor estático se ejecutará solo en un hilo y establecerá el valor para su hilo; todos los otros hilos tendrán este valor sin inicializar)

Hay una diferencia notable entre los campos const y readonly en C # .Net

const es estático por defecto y debe inicializarse con un valor constante, que no puede modificarse más adelante. El cambio de valor tampoco está permitido en los constructores. No se puede usar con todos los tipos de datos. Por ejemplo, DateTime. No se puede usar 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 readonly string Name = string.Empty; //No error, legal

readonly puede declararse 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 el constructor. Por lo tanto, da ventaja cuando se usa como miembro de clase de instancia. Dos instancias diferentes pueden tener un valor diferente de campo de solo lectura. Por ejemplo:

class A
{
    public readonly int Id;

    public A(int i)
    {
        Id = i;
    }
}

Luego, el campo de solo lectura se puede inicializar con valores específicos instantáneos, de la siguiente manera:

A objOne = new A(5);
A objTwo = new A(10);

Aquí, instancia objOne tendrá el valor del campo de solo lectura como 5 y objTwo tiene 10. Lo que no es posible usando const.

¿En uso? Realmente no. Los concursos se evalúan en tiempo de compilación, mientras que los de solo lectura se evalúan en tiempo de ejecución. También puede asignar a una variable de solo lectura un valor en el constructor.

Una cosa más. No vi esto en los comentarios anteriores, aunque es posible que lo haya extrañado. No puede crear una matriz constante.

private const int[] values = new int[] { 1, 2, 3 };

Pero usted puede crearlo usando un campo de solo lectura estático.

private static readonly int[] values = new int[] { 1, 2, 3 };

Entonces, si necesita una constante de matriz, como una lista de valores permitidos, y una enumeración no sería apropiada, entonces la lectura estática es el único camino a seguir. Por ejemplo, si la matriz fuera de enteros anulables, así:

private static readonly int?[] values = new int?[] { null, 1, 2, 3 };

No se puede hacer eso con una constante, ¿verdad?

La diferencia es que el valor de un campo de solo lectura estático se establece en tiempo de ejecución y, por lo tanto, puede ser modificado por la clase que lo contiene, mientras que el valor de un campo constante se establece en una constante de tiempo de compilación.

En el caso de solo lectura estática, la clase que lo contiene solo puede modificarlo

en la declaración de variable (a través de un inicializador de variable) en el constructor estático (constructores de instancias, si no es estático) la lectura estática se usa típicamente si el tipo de campo no está permitido en una declaración constante o cuando el valor no se conoce en tiempo de compilación.

Los campos de solo lectura de instancia también están permitidos.

Recuerde que para los tipos de referencia, en ambos casos (estático e instancia), el modificador de solo lectura solo le impide asignar una nueva referencia al campo. Específicamente no hace inmutable el objeto señalado por la referencia.

class Program

{

  public static readonly Test test = new Test();

  static void Main(string[] args)

  {

     test.Name = "Program";

     test = new Test(); // Error: A static readonly field cannot be assigned to (except in a static constructor or a variable initializer)

  }

}

class Test

{

   public string Name;

}

La diferencia es que la clase que contiene solo puede modificar la lectura estática, pero la constante nunca puede modificarse y debe inicializarse a una constante de tiempo de compilación. Para expandir un poco el caso de solo lectura estático, la clase que lo contiene solo puede modificarlo:

- en la declaración de variable (a través de un inicializador de variable).

- en el constructor estático (constructores de instancias si no es estático).


Palabra clave Const en C # .NET

Ejemplo: public const string abc = “xyz”; Inicializado solo en la declaración. El valor se evalúa en tiempo de compilación y no se puede cambiar en tiempo de ejecución. Un intento de cambiarlo provocará un error de compilación. Const ya es algo estático. Dado que las clases y las estructuras se inicializan en tiempo de ejecución con una nueva palabra clave, no puede establecer una constante para una clase o estructura. Pero, tiene que ser uno de los tipos integrales. Palabra clave de solo lectura en C # .NET

Ejemplo: public readonly string abc; Se puede inicializar en el código de declaración o en el código del constructor. El valor se evalúa en tiempo de ejecución. Se puede declarar como atributo estático o de nivel de instancia. Un campo de solo lectura puede contener un objeto complejo utilizando la nueva palabra clave en tiempo de ejecución.

Los

campos de solo lectura se pueden inicializar en la declaración o en un constructor de una clase. Por lo tanto, los campos de solo lectura pueden tener valores diferentes según el constructor utilizado .

Un miembro de solo lectura también se puede usar para constantes de tiempo de ejecución como en el siguiente ejemplo:

public static readonly uint currentTicks = (uint)DateTime.Now.Ticks;
Los

campos de solo lectura son no implícitamente estáticos y, por lo tanto, la palabra clave estática puede (debe) aplicarse a un campo de solo lectura explícitamente si es necesario. Esto no está permitido para los campos constantes, que son implícitamente estáticos.

Los

miembros de solo lectura pueden contener objetos complejos mediante el uso de la nueva palabra clave en la inicialización .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top