I have this code in an assembly:
public class Class1
{
public const int x = 10;
}
and in a different assembly I have:
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Class1.x);
Console.ReadKey();
}
}
Of course the output was 10
, but then I changed x
to 20
:
public class Class1
{
public const int x = 20;
}
I recompiled the assembly and moved it to my command line program's bin directory. However, the output of my program was still 10
, until I compiled assembly containing the main
function.
Why is this happening?
As the name suggests, constants should not change during runtime and in my opinion constants are defined to not change for a long term (you may look at this SO question for more information.
Variables declared using the const keyword are also known as compile-time constants. It should be noted that a constant variable is immutable, i.e., the value assigned to a constant variable cannot be changed later.
Constants are declared with the const modifier. Only the C# built-in types (excluding System. Object) may be declared as const . User-defined types, including classes, structs, and arrays, cannot be const .
The constants refer to fixed values that the program may not alter during its execution. These fixed values are also called literals. Constants can be of any of the basic data types like an integer constant, a floating constant, a character constant, or a string literal.
Constants values in C# are in-lined in place where they are used. I.e. line Console.WriteLine(Class1.x);
will be compiled to Console.WriteLine(10);
. Generated IL-code will look like:
.entrypoint
.maxstack 8
IL_0000: nop
IL_0001: ldc.i4.s 10 // here just integer value 10 is loaded on stack
IL_0003: call void [mscorlib]System.Console::WriteLine(int32)
There will not be any link to Class1. So, until you re-compile Main
assembly, it will have in-lined value 10
. MSDN has warning about this case of constants usage:
Don’t create a constant to represent information that you expect to change at any time. For example, don’t use a constant field to store the price of a service, a product version number, or the brand name of a company. These values can change over time, and because compilers propagate constants, other code compiled with your libraries will have to be recompiled to see the changes.
They mention that constant expressions are evaluated only at compile time. I.e. Class1.x
will be evaluated at Main
assembly compile time to value 10
. And without re-compilation that value will not change. But unfortunately it does not clearly explains reason of such behavior (to me at least).
BTW Named and Optional parameters values are also in-lined in place where method is called, and you also need to re-compile caller assembly to update values.
This is a technique called constant folding used in compiling. In short, the compiler look for values that can be determined at compile time, computes those values, and write them directly in the exe file. This speeds up the execution of the final machine code. This technique applies to other many compiled languages, such as C, C++ as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With