问题描述
关于这个主题有很多问题,但没有一个(除了 一个但仍然很短) 正在处理以下场景.
There are many questions about this subject , but none (except one but still a short one) are dealing with the following scenario.
来自 C# 4 书:
马克还写道:
如果你改变了一个 const 的值,你需要重建所有的客户
if you change the value of a const, you need to rebuild all the clients
问题:
1) 为什么会这样?static readonly
和 const
都是 static
吗?
1) Why is that? Are both static readonly
and const
— static
?
2) 这些值实际上保存在哪里?
2) Where actually the values are saved ?
3) 使字段static readonly
实际上是如何解决
幕后"这个问题的?
3) How does making a field static readonly
actually solve
this problem "behind the scene" ?
推荐答案
不,const 是 const,而不是 static - 它是一种特殊情况,具有不同的规则;它仅在编译时(而非运行时)设置,并且处理方式不同
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;
对
var bar = SomeType.ConstValue;
在 first 的情况下,它在运行时从 SomeType
读取值,即通过 ldsfld
;但是,在第二种情况下,即编译为值,即如果ConstValue
恰好是123
,那么第二种是等同于:
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;
在运行时,它来自 SomeType
的事实不存在,因为值 (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.
改为static readonly
表示保留从SomeType
加载值".
Changing to static readonly
means that the "load the value from SomeType
" is preserved.
所以如下:
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;
}
编译为:
.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
}
请注意,在 Bar
中,ldc
正在加载一个值 直接 (0x1c8 == 456),使用 Test
完全消失了.
Note that in the Bar
, the ldc
is loading a value directly (0x1c8 == 456), with Test
completely gone.
为了完整起见,const 是用一个静态字段实现的,但是 - 它是一个 literal 字段,意思是:在编译器中计算,而不是在运行时.p>
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
这篇关于静态只读与 const — 不同的程序集 POV?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!