将局部变量声明为const

时间:2010-06-29 13:13:08

标签: c# const

显然,将局部变量声明为const可以防止运行时修改。 Const个实例变量是静态的(我相信)。这是否与const局部变量的性质和用途有关? (例如线程)

7 个答案:

答案 0 :(得分:16)

const不是变量,这就是它被称为常数的原因。

答案 1 :(得分:11)

“const”变量必须具有基本类型(例如int,bool)。每当源代码中出现“const”变量时(无论是本地变量还是全局变量),此实例都将替换为const值本身。所以:

const int foo = 42;
return foo + 69;
优化后

变为:

return 42 + 69

或者更确切地说:

return 111;

没有线程问题,因为const变量具有基本类型,并且它们仅在编译时存在。

答案 2 :(得分:9)

常量不是变量,实际上并不存储在任何地方。因为它没有存储,所以它不是实例成员,并且它不是静态的。

常量只是值的名称。编译代码时,会在使用常量的位置插入值。 (如果您使用在不同程序集中声明的常量,则会产生影响。更改常量的声明值不会更改在重新编译使用常量的代码之前使用的值。)

因此,在本地声明的常量与其他地方声明的常量完全相同,只是范围不同。

答案 3 :(得分:2)

我需要插话说我觉得已经给出的共识答案并不完整。

自由地总结这些答案,我们的共识是我们应该考虑以下代码不是变量声明,而是一种宏声明,其中编译器在使用标识符的任何地方内联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"。

声明常量

不可否认,"内存位置" part是一种延伸 - 我认为这意味着const值在编译期间存储在本地某处。如其他地方所述,您无法在代码中访问或引用此内存。否则,这似乎与我在C#语言规范中读到的内容一致:

  

8.5.2本地常量声明

     

local-constant-declaration 声明一个或多个局部常量。

     

局部常数声明:

     
    

const type {constant-declarators,} constant-declarator

  
     

常数说明符:

     
    

identifier = constant-expression

  

  

7.19常量表达式

     

常量表达式是一个可以在编译时完全评估的表达式。

     

常量表达式:

     
    

表达

  
     

...

     

只要表达式满足上面列出的要求,就会在编译时计算表达式。即使表达式是包含非常量构造的较大表达式的子表达式,也是如此。

有关此问题的任何反馈" quanser"欢迎:^)

答案 4 :(得分:1)

由于每个方法调用都会创建自己的堆栈区域,因此拥有自己的局部变量,因此您无需担心从其他线程修改的本地变量。

AFAIK在c#中将locals创建为const将根本不会创建任何变量或字段,而是在方法中使用它的任何地方都会将指定的常量值放在内联中。

答案 5 :(得分:1)

本地使用const的主要优点是,您不会意外地将标识符设置为可能会更改代码正确性的其他值。

答案 6 :(得分:-3)

我也将其发布到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