There are many questions about this subject , but none (except one but still a short one) are dealing with the following scenario.
From C# 4 book:
Marc also wrote :
if you change the value of a const, you need to rebuild all the clients
Question :
1) Why is that? Are both static readonly
and const
— static
?
2) Where actually the values are saved ?
3) How does making a field static readonly
actually solve
this problem "behind the scene" ?
The first, const, is initialized during compile-time and the latter, readonly, initialized is by the latest run-time. The second difference is that readonly can only be initialized at the class-level. Another important difference is that const variables can be referenced through "ClassName.
Difference between const and readonlyconst variables can declared in methods ,while readonly fields cannot be declared in methods. const fields cannot be used with static modifier, while readonly fields can be used with static modifier.
Constant variables cannot be modified after declaration. Static members can be accessed using ClassName. StaticMemberName , but cannot be accessed using object. Readonly members can be accessed using object, but not ClassName.
ReadOnly is a runtime constant. Const is a compile time constant. The value of readonly field can be changed. The value of the const field can not be changed.
no, a const is a const, not a static - it is a special-case, with different rules; it is only set at compile-time (not runtime), and it is handled differently
the crux here is what the following means:
var foo = SomeType.StaticValue;
vs
var bar = SomeType.ConstValue;
in the first case, it reads the value at runtime from SomeType
, i.e. via a ldsfld
; however, in the second case, that is compiled to the value, i.e. if ConstValue
happens to be 123
, then the second is identical to:
var bar = 123;
at runtime, the fact that it came from SomeType
does not exist, as the value (123
) was evaluated by the compiler, and stored. Hence it needs a rebuild to pick up new values.
Changing to static readonly
means that the "load the value from SomeType
" is preserved.
So the following:
static int Foo()
{
return Test.Foo;
}
static int Bar()
{
return Test.Bar;
}
...
static class Test
{
public static readonly int Foo = 123;
public const int Bar = 456;
}
compiles as:
.method private hidebysig static int32 Bar() cil managed
{
.maxstack 8
L_0000: ldc.i4 0x1c8
L_0005: ret
}
.method private hidebysig static int32 Foo() cil managed
{
.maxstack 8
L_0000: ldsfld int32 ConsoleApplication2.Test::Foo
L_0005: ret
}
Note that in the Bar
, the ldc
is loading a value directly (0x1c8 == 456), with Test
completely gone.
For completeness, the const is implemented with a static field, but - it is a literal field, meaning: evaluated at the compiler, not at runtime.
.field public static literal int32 Bar = int32(0x1c8)
.field public static initonly int32 Foo
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