Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Static readonly vs const — different assemblies POV?

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:

enter image description here

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 conststatic?

2) Where actually the values are saved ?

3) How does making a field static readonly actually solve this problem "behind the scene" ?

like image 557
Royi Namir Avatar asked Feb 02 '12 09:02

Royi Namir


People also ask

What is the difference between static const and read only?

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.

What is difference between static constant and readonly variables?

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.

What is the difference between the static const and readonly keyword when applied to a type member?

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.

Can readonly and const be used interchangeably?

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.


1 Answers

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
like image 174
Marc Gravell Avatar answered Sep 23 '22 15:09

Marc Gravell