【发布时间】:2010-06-29 13:13:08
【问题描述】:
显然,将局部变量声明为const,可以防止运行时修改。 Const 实例变量是静态的(我相信)。这对const 局部变量的性质和使用有任何影响吗? (例如线程)
【问题讨论】:
-
如果您想要明确地描述常量字段,您最好阅读 C# 规范的第 10.4 节。这里的各种答案似乎有相当多的错误信息等等。
显然,将局部变量声明为const,可以防止运行时修改。 Const 实例变量是静态的(我相信)。这对const 局部变量的性质和使用有任何影响吗? (例如线程)
【问题讨论】:
“const”变量必须具有原始类型(例如 int、bool)。每当源代码中出现“const”变量时(无论是本地的还是全局的),此实例都会被 const 值本身替换。所以:
const int foo = 42;
return foo + 69;
优化后变为:
return 42 + 69
或者说:
return 111;
不存在线程问题,因为 const 变量具有原始类型并且它们仅在编译时存在。
【讨论】:
const 不是变量,这就是为什么它被称为常量。
【讨论】:
常量不是变量,它实际上并不存储在任何地方。因为它没有被存储,所以它不是实例成员,也不是静态的。
常量只是一个值的名称。编译代码时,会将值插入到使用常量的位置。 (如果您使用在不同程序集中声明的常量,这会产生影响。更改常量的声明值不会更改使用的值,直到您重新编译使用该常量的代码。)
因此,在本地声明的常量与在其他任何地方声明的常量完全相同,只是范围不同。
【讨论】:
我需要插话说我觉得已经给出的共识答案不完整。
冒昧地总结一下这些答案,共识是我们应该考虑以下代码不是变量声明,而是一种宏声明,其中编译器在使用标识符的地方内联 const 值:
const int foo = 42;
但是,如果使用(可能很复杂的)常量表达式声明 const “变量”,则该答案回避了出现的问题,如下所示:
const double H = 1.23e-2, Q = 7.65e-4, nu = 0.3;
const double Reynolds = H*H*H*H / Q / (1d - nu);
在这种情况下,编译器是对表达式求值一次并“存储”结果以供重复使用(如静态变量),还是在每次使用标识符时执行表达式(如C/C++ 中的#define 宏)。
在我自己的探索中,我在http://www.techopedia.com/definition/3768/constant-c 中找到了与此问题相关的以下描述:
在 C# 的上下文中,常量是一种字段或局部变量,其值在编译时设置,并且在运行时永远不能更改。它类似于变量,具有名称、值和内存位置。但是,它与变量的不同之处在于其在应用程序中只被初始化一次的特性。使用关键字“const”声明一个常量。
诚然,“内存位置”部分有点牵强——我认为它的意思是 const 值在编译期间存储在本地某处。如其他地方所述,您永远无法在代码中访问或引用此内存。否则,这似乎与我在 C# 语言规范中读到的一致:
8.5.2 局部常量声明
local-constant-declaration 声明一个或多个局部常量。
本地常量声明:
常量类型{常量声明符,}常量声明符
常量声明符:
标识符 = 常量表达式
还有:
7.19 常量表达式
constant-expression 是可以在编译时完全计算的表达式。
常量表达式:
表达式
...
只要表达式满足上面列出的要求,就会在编译时评估该表达式。即使表达式是包含非常量结构的较大表达式的子表达式也是如此。
欢迎对此“quanser”的任何反馈:^)
【讨论】:
const 做了 C++ 宏会做的事情,并在代码中的任何地方删除整个未计算的表达式,每个这些单独的表达式将在编译时计算为单个常量值。在将值放在使用的任何地方之前进行一次计算会加快 编译 时间(我确信它会这样做),但它不会影响程序的执行速度。
由于每个方法调用都会创建自己的堆栈区域,因此拥有自己的局部变量,因此您无需担心局部变量会被其他线程修改。
AFAIK 在 c# 中将局部变量创建为 const 根本不会创建任何变量或字段,而是分配的常量值将内联放置在您在方法中使用它的任何地方。
【讨论】:
在本地使用const 的主要优点是您不会意外地将标识符设置为另一个可能会改变代码正确性的值。
【讨论】:
我也把这个发到Why can't I declare a constant using var in C#?
没有 var 的常量:
const int Value1 = 1;
const int Value2 = 2;
带 var 的常量(匿名类型属性值创建后无法更改):
var constants = new {
Value1 = 1,
Value2 = 2,
};
//use as constants.Value1
【讨论】: