我有一个问题。最近我发现自己使用了3种不同的代码,经过仔细检查后看起来和感觉都一样。
public static class constant
{
public static readonly int val1 = 5;
public const int val2 = 5;
public static int val3 { get { return 5; } }
}
我的问题是,它们是否相同,是否应该使用另一个?如果是这样。当α
作为视觉工作室中的一个额外问题,为什么它们在智能感知中的表现方式不同?
答案 0 :(得分:9)
声明为readonly的成员可以在类的(静态)构造函数中进行更改,而const成员不能在运行时更改。
将一个字段声明为const使其自动静态,引用§10.3.7:
当字段,方法,属性,事件,运算符或构造函数时 声明包含一个静态修饰符,它声明一个静态成员。 另外,常量或类型声明隐式声明了一个 静态成员。
第三个只是一个只读属性,总是返回5.
你永远不应该使用这样的属性,并且尽可能选择const成员,以便允许编译器和/或抖动执行它们的优化并帮助其他人阅读你的代码(该属性对我来说是一种WTF) 。如果需要在程序启动期间初始化的常量值(例如,机器的核心数),则必须使用静态只读成员。
这是C#规范(§10.5.2.1)中的一个很好的例子:
静态只读字段在常量的符号名称时很有用 期望值,但是当a中不允许值的类型时 const声明,或者当无法计算值时 编译时间。在示例中
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;
}
}
黑色,白色,红色,绿色和蓝色成员不能声明为 const成员,因为它们的值无法在编译时计算。 然而,将它们声明为静态只读而已大致相同 影响。
还有另一个区别(§10.5.2.2):
常量和只读字段具有不同的二进制版本 语义。当表达式引用常量时,该值为 常量是在编译时获得的,但是当表达式时 引用只读字段,不获取字段的值 直到运行时间。
所以,总结起来,即使乍一看它们看起来很相似也是非常不同的,你应该使用最适合你意图的那个。
答案 1 :(得分:0)
静态只读可以在constroctor分配,而const则不能。此外,getter不必返回常量值,值van是私有成员,可以在类的另一部分中更改,或者是计算值。
readonly关键字与const关键字不同。一个常数 字段只能在字段声明中初始化。一个 readonly字段可以在声明处或在a中初始化 构造函数。因此,只读字段可以具有不同的值 取决于使用的构造函数。此外,虽然const字段是a 编译时常量,readonly字段可用于运行时 常量如下例所示:
public static readonly uint timeStamp = (uint)DateTime.Now.Ticks;
readonly关键字是一个可以在字段上使用的修饰符。当一个 字段声明包括一个只读修饰符,赋值给 声明引入的字段只能作为其中的一部分出现 声明或在同一类的构造函数中。
const关键字用于修改字段或本地的声明 变量。它指定字段或本地的值 变量是常量,这意味着它不能被修改。
此外,intellisense中的不同之处在于它们是不同的编译时对象
答案 2 :(得分:0)
您应该尽可能使用const
ant字段 - 但这仅适用于基本类型。
如果您需要自定义类型(比如您自己的类或结构),则应使用public static property
。
公共字段仅在结构中使用,我不记得任何我看到任何公共静态只读字段的情况。
答案 3 :(得分:0)
在字段定义中使用const
或readonly
时。 const限定符可以与primitive data
类型和字符串一起使用。使用时,分配给const字段的值将直接插入生成的IL代码中的所有引用中。其他组件也是如此。引用该const字段的其他程序集被编译为好像它们直接使用了值本身。只读字段是运行时常量。它们在内存中占据一些位置,并且它们的引用在运行时被解析,就像我们引用了一个普通变量一样。实际上它们是类似常量的变量。
const:
作为一般规则,尽量避免使用常量,因为该值不仅硬编码到声明它们的程序集中,而且还指向引用常量值的任何程序集。这可能会产生一些真正奇怪的问题。
readonly:
答案 4 :(得分:0)
Const是在编译时计算的表达式。编译器可以将值直接嵌入其使用的每个位置。静态只读将仅在运行时进行评估,如果您认为稍后可能会更改该值,因为针对您编译的程序集将不会嵌入静态只读值,这可能会发生在const中。注意一些像DateTime.Now这样的值不能存储在const中,因为它必须在运行时对属性进行评估。您可以使用静态只读,它将类似于const,但它将在运行时捕获该值。
最后一个属性可以做的不仅仅是返回一个值。它可能是Web服务调用或复杂计算的结果。请注意,编译器中属性中的代码可能会获得inlined。
您使用哪一个取决于您想要的语义。
答案 5 :(得分:0)
答案 6 :(得分:0)
我只是解释你的第一个问题。
常量;成员应该在编译时给出初始值,然后它们不能被更改。静态只读;成员的值不必分配为初始化,然后分配。预约后不能更改一次。
静态只读成员可以从它们所属的类中访问,并且可以分配值。必须完成要赋予成员值的值的第一个赋值,或者应在事务中创建静态构造函数。