variable define constant c# coding-style resharper const

define - static vs const c#



Ventajas de usar const en lugar de variables dentro de los métodos (8)

Además de la pequeña mejora en el rendimiento, cuando declaras una constante estás aplicando explícitamente dos reglas sobre ti y otros desarrolladores que usarán tu código

  1. Tengo que inicializarlo con un valor en este momento, no puedo hacerlo en ningún otro lugar.
  2. No puedo cambiar su valor en ninguna parte.

En el código, todo se trata de legibilidad y comunicación.

Cada vez que tengo variables locales en un método, ReSharper sugiere convertirlas a constantes:

// instead of this: var s = "some string"; var flags = BindingFlags.Public | BindingFlags.Instance; // ReSharper suggest to use this: const string s = "some string"; const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;

Dado que estos son valores realmente constantes (y no variables), entiendo que ReSharper sugiera cambiarlos a const.

Pero aparte de eso, ¿hay alguna otra ventaja al usar const (por ejemplo, un mejor rendimiento) que justifique el uso de const BindingFlags lugar de la palabra clave var práctica y legible?

Por cierto: acabo de encontrar una pregunta similar aquí: Resharper siempre me sugiere hacer cadenas const en lugar de cuerdas , pero creo que se trata más de campos de una clase donde mi pregunta es sobre variables / constras locales.


El compilador emitirá un error si intenta asignar un valor a una constante, lo que posiblemente le impida cambiar accidentalmente.

Además, generalmente hay un pequeño beneficio de rendimiento al usar constantes vs. variables. Esto tiene que ver con la forma en que se compilan en el MSIL, por este Q & A de la revista MSDN :

Ahora, siempre que se haga referencia a myInt en el código, en lugar de tener que hacer un "ldloc.0" para obtener el valor de la variable, el MSIL simplemente carga el valor constante que está codificado en el MSIL. Como tal, generalmente hay una pequeña ventaja de rendimiento y memoria en el uso de constantes. Sin embargo, para usarlos debe tener el valor de la variable en tiempo de compilación, y cualquier referencia a esta constante en tiempo de compilación, incluso si están en un ensamblaje diferente, tendrá esta sustitución realizada.

Las constantes son ciertamente una herramienta útil si conoce el valor en tiempo de compilación. Si no lo hace, pero quiere asegurarse de que su variable esté configurada solo una vez, puede usar la palabra clave readonly en C # (que se asigna a initlyly en MSIL) para indicar que el valor de la variable solo se puede establecer en el constructor; después de eso, es un error cambiarlo. Esto se usa a menudo cuando un campo ayuda a determinar la identidad de una clase, y a menudo se establece igual a un parámetro de constructor.


La palabra clave const le dice al compilador que se puede evaluar completamente en tiempo de compilación. Hay una ventaja de rendimiento y memoria en esto, pero es pequeño.


Las constantes en C # proporcionan una ubicación con nombre en la memoria para almacenar un valor de datos. Significa que el valor de la variable se conocerá en tiempo de compilación y se almacenará en un solo lugar.

Cuando lo declara, está como ''codificado'' en Microsoft Intermediate Language (MSIL).

Aunque un poco, puede mejorar el rendimiento de su código. Si declaro una variable y puedo convertirla en una constante, siempre lo hago. No solo porque puede mejorar el rendimiento, sino también porque esa es la idea de las constantes. De lo contrario, ¿por qué existen?

Reflector puede ser realmente útil en situaciones como esta. Intente declarar una variable y luego hacerla constante, y ver qué código se genera en IL . Entonces, todo lo que necesita hacer es ver la diferencia en las instrucciones y ver qué significan esas instrucciones.


Según mi comprensión, los valores de Const no existen en el tiempo de ejecución, es decir, en forma de una variable almacenada en alguna ubicación de memoria, están embebidos en código MSIL en tiempo de compilación. Y, por lo tanto, tendría un impacto en el rendimiento. No se requerirá más tiempo de ejecución para realizar mantenimiento de casa (verificaciones de conversión / recolección de basura, etc.) en ellos, donde las variables requieren estas comprobaciones.


Un valor const también se ''comparte'' entre todas las instancias de un objeto. También podría reducir el uso de memoria.

Como ejemplo:

public class NonStatic { int one = 1; int two = 2; int three = 3; int four = 4; int five = 5; int six = 6; int seven = 7; int eight = 8; int nine = 9; int ten = 10; } public class Static { static int one = 1; static int two = 2; static int three = 3; static int four = 4; static int five = 5; static int six = 6; static int seven = 7; static int eight = 8; static int nine = 9; static int ten = 10; }

El consumo de memoria es complicado en .Net y no voy a pretender entender los detalles más sutiles, pero si crea una lista con un millón de "Estática", es probable que use considerablemente menos memoria que si no lo hace.

static void Main(string[] args) { var maxSize = 1000000; var items = new List<NonStatic>(); //var items = new List<Static>(); for (var i=0;i<maxSize;i++) { items.Add(new NonStatic()); //items.Add(new Static()); } Console.WriteLine(System.Diagnostics.Process.GetCurrentProcess().WorkingSet64); Console.Read(); }

Cuando se usa ''NonStatic'', el conjunto de trabajo es 69,398,528 comparado con solo 32,423,936 cuando se usa estático.


const es una constante de tiempo de compilación, eso significa que todo su código que está usando la variable const está compilado para contener la expresión constante que contiene la variable const - el IL emitido contendrá ese valor constante en sí mismo.

Esto significa que la huella de memoria es menor para su método porque la constante no requiere que se asigne ninguna memoria en tiempo de ejecución.


tl; dr para variables locales con valores literales, const no hace ninguna diferencia en absoluto.

Su distinción de "métodos internos" es muy importante. Veámoslo, luego compárelo con los campos const .

Variables locales de Const

El único beneficio de una variable local const es que el valor no puede ser reasignado.

Sin embargo, const está limitado a tipos primitivos ( int , double , ...) y string , lo que limita su aplicabilidad.

Digresión: hay propuestas para que el compilador de C # permita un concepto más general de locals ''readonly'' ( here ) que extendería este beneficio a otros escenarios. Sin embargo, probablemente no se los considere const , y probablemente tengan una palabra clave diferente para tales declaraciones (es decir, let o readonly var o algo así).

Considera estos dos métodos:

private static string LocalVarString() { var s = "hello"; return s; } private static string LocalConstString() { const string s = "hello"; return s; }

Construido en modo Release , vemos el siguiente IL (abreviado):

.method private hidebysig static string LocalVarString() cil managed { ldstr "hello" ret } .method private hidebysig static string LocalConstString() cil managed { ldstr "hello" ret }

Como puede ver, ambos producen exactamente la misma IL. Si el local es const o no tiene ningún impacto.

Lo mismo es cierto para los tipos primitivos. Aquí hay un ejemplo usando int :

private static int LocalVarInt() { var i = 1234; return i; } private static int LocalConstInt() { const int i = 1234; return i; }

Y de nuevo, el IL:

.method private hidebysig static int32 LocalVarInt() cil managed { ldc.i4 1234 ret } .method private hidebysig static int32 LocalConstInt() cil managed { ldc.i4 1234 ret }

Entonces, de nuevo, no vemos diferencia. No puede haber una diferencia de rendimiento o memoria aquí. La única diferencia es que el desarrollador no puede volver a asignar el símbolo.

Campos de Const

La comparación de un campo const con un campo variable es diferente. Un campo no const debe leerse en tiempo de ejecución. Entonces terminas con IL así:

// Load a const field ldc.i4 1234 // Load a non-const field ldsfld int32 MyProject.MyClass::_myInt

Está claro cómo esto podría generar una diferencia en el rendimiento, suponiendo que el JIT no puede alinear un valor constante.

Otra diferencia importante aquí es para los campos de const públicos que se comparten entre ensamblados. Si un ensamblaje expone un campo const, y otro lo usa, entonces el valor real de ese campo se copia en tiempo de compilación . Esto significa que si el conjunto que contiene el campo const se actualiza pero el conjunto que lo usa no se vuelve a compilar, entonces se usará el valor anterior (y posiblemente incorrecto).