Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C#中声明局部范围内的常数有什么好处吗?_C#_Constants - Fatal编程技术网

在C#中声明局部范围内的常数有什么好处吗?

在C#中声明局部范围内的常数有什么好处吗?,c#,constants,C#,Constants,如果我知道不会改变局部变量的值,那么将其声明为“const”有什么好处吗 谢谢,是的。您将保护代码不被意外更改此变量。将局部变量声明为常量将让编译器知道您的意图,因此您将无法在函数的其他位置更改变量的值。您通常会在整个解决方案中使用常量。但是在本地范围中使用的好处是,您知道范围中的其他地方,您不会更改它。而且,如果其他人正在处理此代码,他们也会知道不要更改它。 这使您的程序更易于维护,因为您只需要维护常量(即使它只是在本地范围内)进一步,您不仅要告诉编译器该值不会更改,还可以根据使用情况快速告诉

如果我知道不会改变局部变量的值,那么将其声明为“const”有什么好处吗


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

将局部变量声明为常量将让编译器知道您的意图,因此您将无法在函数的其他位置更改变量的值。

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

进一步,您不仅要告诉编译器该值不会更改,还可以根据使用情况快速告诉其他人将查看您的代码。

比如说,

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

    new XmlDocument().SelectNodes(xpath);
}

在这种情况下,我认为const声明是没有意义的

声明变量const还将允许编译器进行优化-而不是说在堆栈上分配一个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

优化到

.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
这是使用2010年发布的优化


我进行了一次搜索,以了解有关常数传播的更多信息,虽然可能,但当前编译器不会像前面提到的那样执行此操作

我喜欢在将布尔标志指示器传递给方法时执行此操作:

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

对我来说,这比简单的true/false更容易理解,后者需要阅读方法声明来确定其含义。

我为其他程序员声明局部常量比其他任何原因都重要。将常量声明为变量有什么好处吗?我喜欢这一点。我注意到微软似乎在其源代码中做到了这一点:base.Compute(10,true/*includefo*/);在C#4.0中,您可以使用命名参数来完成相同的任务(希望参数有合理的名称!)这不是引入它们的目的,但它们的优点是确保您使用正确的名称(在带有许多这样的标志的调用中使用const locals或comments可能会使它们意外混淆)。当我设计自己的接口时,我现在倾向于首先避免使用布尔参数,或者创建不同的公共方法,映射到具有标志的内部方法,或者使用枚举值作为标志。我仍然发现,在与采用布尔或“魔法”参数的API进行交互操作时,此技术很有用(如string.Empty表示“缺少”)。我认为这仍然有价值,原因之一是一致性。如果您总是使用局部scope const规则,那么您就不太可能在更有利的地方忘记它(您在这里使用它不会丢失任何东西,而且也不会有太多额外的键入)。此外,如果此函数将来会变大,您无需担心有人在未实现初始意图的情况下进一步更改范围中的值。即使您不将变量标记为常量,优化器也会轻松确定您的变量是常量,然后生成上述代码。它被称为“持续传播”。@Roubachof我以前没听说过“持续传播”,谢谢你的评论。我在阅读时找到了一个链接,编辑了我的答案;结果是当前的编译器没有做到这一点——也许在将来!(一旦他们在2010年修复了当前的bug!)真的吗?这是一个非常基本的优化技术,我对这个消息感到非常惊讶。干得好!
const bool includeFoo = true;
int result = bar.Compute(10, includeFoo);