A Very similar to a #define in C, const “variables” in the .NET Framework don’t have their own actual storage location but rather are substituted into the Microsoft Intermediate Language (MSIL) instructions at compile time where they are referenced. For example, if I have the following C# code
int myInt = 5;
csc.exe will generate this MSIL:
ldc.i4.5 stloc.0 ldloc.0 call void [mscorlib]System.Console::WriteLine(int32)
In other words, it loads the value 5, stores it to the myInt variable, then loads this value back onto the execution stack, and prints it out using Console.WriteLine.
If you change the myInt variable to be a constant, like so
const int myInt = 5;
the MSIL generated will be:
ldc.i4.5 call void [mscorlib]System.Console::WriteLine(int32)
Now, wherever myInt is referenced in the code, instead of having to do a “ldloc.0” to get the value from the variable, the MSIL just loads the constant value which is hardcoded into the MSIL. As such, there’s usually a small performance and memory advantage to using constants.
However, in order to use them you must have the value of the variable at compile time, and any references to this constant at compile time, even if they’re in a different assembly, will have this substitution made. Constants are certainly a useful tool if you know the value at compile time.
If you don’t, but want to ensure that your variable is set only once, you can use the readonly keyword in C# (which maps to initonly in MSIL) to indicate that the value of the variable can only be set in the constructor; after that, it’s an error to change it. This is often used when a field helps to determine the identity of a class, and is often set equal to a constructor parameter.