c# static constants

c# - ¿Por qué las constantes se pueden convertir implícitamente mientras que los campos de solo lectura estáticos no pueden?



c# readonly modifier (3)

Debido a que los campos constantes se evalúan en tiempo de compilación, mientras que los campos de readonly se evalúan en tiempo de ejecución. El intérprete en el compilador trata sus enteros de manera diferente a como lo hace el tiempo de ejecución.

El compilador reconoce el valor y su tipo y puede hacer algunas conversiones básicas basadas en eso, como lo hace en este caso. Intente ver qué sucede si establece ConstantInt en un número negativo. El compilador dará error. Lo mismo ocurre cuando cambia el tipo a long o float : no hay una regla de conversión del compilador, por lo que también se produce un error.

Dado el siguiente código, me pregunto por qué referenceValue = ConstantInt; es válido mientras referenceValue = StaticInt; no se compila

namespace Demo { public class Class1 { private const int ConstantInt = 42; private static readonly int StaticInt = 42; public void DemoMethod(ref uint referenceValue) { referenceValue = ConstantInt; // This compiles referenceValue = StaticInt; // This claims that the source type ''int'' cannot be converted to ''unit'' implicitly. } } }


Las constantes se reemplazan en tiempo de compilación con su valor respectivo. Así que desde la perspectiva del compilador este referenceValue = ConstantInt; es el mismo que este valor de referenceValue = 42 .

Mientras que los campos de readonly sienten similares, no lo son. Su valor no es realmente conocido en tiempo de compilación. Están respaldados por un campo estático en la clase. Su valor puede calcularse, incluso modificarse a partir de un constructor estático, por lo que el compilador no puede verificar que el valor esté dentro del rango de uint en el momento de la compilación.

Por ejemplo:

public class Class1 { private const int ConstantInt = 42; private static readonly int StaticInt = 42; static Class1() { StaticInt = -20; } public void DemoMethod(ref uint referenceValue) { referenceValue = StaticInt; // it''s -20 } }

Editar

Como se señala en los comentarios, no todas las asignaciones de constantes a variables funcionan, la constante long a la variable int no funciona sin una conversión explícita. Este comportamiento es el mismo en función del tipo de constante, independientemente de si es una constante con nombre o una constante en línea:

private const long ConstantInt = 42; // Both of these will cause an error: referenceValue = ConstantInt; // can''t be converted implicitly referenceValue = 42L; // but neither can an inline long constant (the L makes it long)


del doc

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

como en esta línea: public static readonly uint l1 = (uint) DateTime.Now.Ticks;