what is the difference between const, readonly and get in a static class
我有个问题。最近我发现自己使用了3行不同的代码,经过仔细检查,它们看起来和感觉都是一样的。
1 2 3 4 5 6 | public static class constant { public static readonly int val1 = 5; public const int val2 = 5; public static int val3 { get { return 5; } } } |
我的问题是,它们是相同的吗?一个应该用在另一个上面吗?如果是这样的话。什么时候?
在Visual Studio中,还有一个额外的问题,为什么它们在IntelliSense中的表示方式都不同?
声明为只读的成员提供了在类的(静态)构造函数中更改的可能性,而常量成员在运行时无法更改。
将字段声明为常量将使其自动静态,引用§10.3.7:
When a field, method, property, event, operator, or constructor
declaration includes a static modifier, it declares a static member.
In addition, a constant or type declaration implicitly declares a
static member.
第三个只是一个只读属性,它总是返回5。
您不应该使用这样的属性,如果可能,为了允许编译器和/或抖动执行它们的优化并帮助其他人读取您的代码,您最好使用const成员(该属性对我来说是一种wtf)。如果需要在程序启动期间初始化的常量值(例如,计算机的内核数),则必须使用静态只读成员。
这是C规范(第10.5.2.1节)中的一个很好的例子:
A static readonly field is useful when a symbolic name for a constant
value is desired, but when the type of the value is not permitted in a
const declaration, or when the value cannot be computed at
compile-time. In the example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public class Color { public static readonly Color Black = new Color(0, 0, 0); public static readonly Color White = new Color(255, 255, 255); public static readonly Color Red = new Color(255, 0, 0); public static readonly Color Green = new Color(0, 255, 0); public static readonly Color Blue = new Color(0, 0, 255); private byte red, green, blue; public Color(byte r, byte g, byte b) { red = r; green = g; blue = b; } } |
the Black, White, Red, Green, and Blue members cannot be declared as
const members because their values cannot be computed at compile-time.
However, declaring them static readonly instead has much the same
effect.
还有一个区别(§10.5.2.2):
Constants and readonly fields have different binary versioning
semantics. When an expression references a constant, the value of the
constant is obtained at compile-time, but when an expression
references a readonly field, the value of the field is not obtained
until run-time.
综上所述,它们是非常不同的,即使乍一看它们可能看起来很相似,你应该使用最适合你意图的。
我只是解释你的第一个问题。
成员应该被赋予初始值吗??在编译时,则不能更改。静态只读;成员的值??无需分配初始化,然后分配。预约后不能更改一次。
静态只读成员可以从其所属的类中访问,并且可以分配值。要分配的值的第一个赋值必须完成成员的值,或者应该在事务中进行静态构造函数。
嗨,你可以在这篇文章中找到问题的答案:
静态只读与常量
您还可以检查IL代码并尝试自己比较结果。
const是编译时计算的表达式。编译器可以将该值直接嵌入其使用的每个位置。静态只读将只在运行时进行计算,如果您认为该值稍后可能会发生更改,则此方法非常有用,因为针对您的程序集编译的程序集不会嵌入静态只读值,而静态只读值可能与常量一起发生。注意一些值,如datetime。现在不能存储在常量中,因为它是对必须在运行时完成的属性的计算。您可以使用静态只读,它将类似于常量,但它将在运行时捕获该值。
最后一个属性可以做的不仅仅是返回一个值。它可能是Web服务调用或复杂计算的结果。注意,属性中的代码可能被编译器内联。
您使用哪一个取决于您想要的语义。
在字段定义中使用
作为一般规则,尽量避免使用常量,因为该值不仅硬编码到声明它们的程序集中,而且还硬编码到引用常量值的任何程序集中。这会产生一些真正奇怪的问题。
- 不能是静态的。
- 值在编译时计算。
- 仅在声明时初始化。
- 可以是实例级的,也可以是静态的。
- 值在运行时计算。
- 可以在声明中或通过构造函数中的代码初始化。
您应该尽可能使用
当您需要自定义类型(比如您自己的类或结构)时,应该使用
公共字段只在结构中使用,并且我无法回忆任何我看到任何公共静态只读字段的情况。
静态只读可以在constroctor处分配,而const不能分配。此外,getter不必返回常量值,值van是私有成员,可以在类的另一部分中更改,也可以是计算值。
从只读(C引用)
The readonly keyword is different from the const keyword. A const
field can only be initialized at the declaration of the field. A
readonly field can be initialized either at the declaration or in a
constructor. Therefore, readonly fields can have different values
depending on the constructor used. Also, while a const field is a
compile-time constant, the readonly field can be used for runtime
constants as in the following example:
1 | public static readonly uint timeStamp = (uint)DateTime.Now.Ticks; |
The readonly keyword is a modifier that you can use on fields. When a
field declaration includes a readonly modifier, assignments to the
fields introduced by the declaration can only occur as part of the
declaration or in a constructor in the same class.
来自常量(C参考)
The const keyword is used to modify a declaration of a field or local
variable. It specifies that the value of the field or the local
variable is constant, which means it cannot be modified.
此外,由于它们是不同的编译时对象,因此在IntelliSense中是不同的