2010-09-03 33 views

回答

5

您通常会在整个解决方案中使用const。但是,在本地范围内使用的好处是,您知道范围内的其他位置不会改变它。而且如果别人正在处理这些代码,他们也会知道不要改变它。 这使得你的程序更易于维护,因为你只需要维护const(即使它只是在本地范围内)

3

是的。您将保护您的代码不会意外更改此变量。

2

声明本地为const将让编译器知道你的意图,所以你将无法在函数的其他地方更改变量的值。

1

除了有效的答案,你不仅告诉编译器该值不会改变,你很快就会告诉别人会看你的代码。

+1

我为其他程序员声明本地consts比其他原因更多。 – 2010-09-03 13:55:52

0

根据使用的情况下..

例如,

void Foo() 
{ 
    const string xpath = "//pattern/node"; 

    new XmlDocument().SelectNodes(xpath); 
} 
在这种情况下

我觉得常量声明是毫无意义的

+1

我认为这仍然有价值,其中一个原因是一致性。如果您始终使用本地范围常量规则,则不太可能在可能更有利的地方将它忘记(不要因此使用它而放弃任何内容,而且它不会额外打字)。另外,如果这个功能在未来会变得更大,您不必担心有人在范围内进一步改变价值,而不会意识到您的初衷。 – cweston 2010-12-29 22:04:31

5

声明变量常量也将让编译器做优化 - 而不是说在栈上分配一个int并将其值放在那里,编译器可能直接使用该值直接与您的代码

即以下内容:回复 “传递” 为评论框有大小限制

使用:

const int test = 4; 
DoSomething(test); 

可以通过编译器

编辑编译为

DoSomething(4); 

ildasm检查常量和非常量之间的优化释放:

代码

int test = 4; 
Console.WriteLine(test*2); 

编译到

.method private hidebysig static void Main(string[] args) cil managed 
{ 
    .entrypoint 
    // Code size  11 (0xb) 
    .maxstack 2 
    .locals init ([0] int32 test) 
    IL_0000: ldc.i4.4 
    IL_0001: stloc.0 
    IL_0002: ldloc.0 
    IL_0003: ldc.i4.2 
    IL_0004: mul 
    IL_0005: call  void [mscorlib]System.Console::WriteLine(int32) 
    IL_000a: ret 
} // end of method Program::Main 

虽然

const int test = 4; 
Console.WriteLine(test*2); 

被优化以

.method private hidebysig static void Main(string[] args) cil managed 
{ 
    .entrypoint 
    // Code size  7 (0x7) 
    .maxstack 8 
    IL_0000: ldc.i4.8 
    IL_0001: call  void [mscorlib]System.Console::WriteLine(int32) 
    IL_0006: ret 
} // end of method Program::Main 

这r被使用2010优化。

我做了搜索,以了解更多关于常量传送和更多钞票的同时,当前的编译器不要这样做提到here

+0

即使您不将变量标记为const,优化程序也会轻松确定您的变量是常量,然后将生成上述代码。它被称为“不断传播”。 – Roubachof 2011-02-22 15:56:32

+0

@Roubachof之前我没有听说过“不断传播”,感谢评论。我在阅读了关于它的链接后编辑了我的答案;事实证明,目前的编译器没有这样做 - 可能在未来! (一旦他们已经修复了2010年的当前错误!) – JLWarlow 2011-02-23 17:01:50

+0

真的吗?这是一个非常基本的优化技术,我真的很惊讶这个消息。做得好! – Roubachof 2011-02-23 18:50:37

3

我喜欢做这个的时候,我路过一个布尔标志指示的方法:

const bool includeFoo = true; 
int result = bar.Compute(10, includeFoo); 

这对我来说比一个简单的true/false更可读,它需要读取方法声明来确定含义。

+1

我喜欢这个丹。我注意到MS似乎在他们的源代码中这样做: base.Compute(10,true/* includeFoo * /); 有剩余一行的好处。 – Nik 2010-09-03 14:15:25

+1

在C#4.0中,您可以使用命名参数来完成相同的事情(希望参数具有合理的名称!)不是它们被引入的名称,但它们的优点是确保您使用正确的名称(使用const locals或注释在与许多这样的标志打电话可能会让他们意外混淆)。 – shambulator 2010-09-03 15:17:28

+1

当我设计我自己的接口时,我现在倾向于首先尝试避免布尔参数,并创建不同的公用方法,这些公用方法可以映射到带有标志的内部方法或使用标志的枚举值。我仍然发现这种技术在与采用布尔或“魔术”参数的API进行互操作时很有用(如string.Empty表示“缺失”)。 – 2010-09-03 17:10:54

相关问题