C#中常量的重点是什么

时间:2010-03-28 04:08:50

标签: c# constants

任何人都能说出C#中常量的含义是什么?

例如,做

的优点是什么
const int months = 12;

而不是

int months = 12;

我知道常量不能改变,但为什么不只是......在初始化之后不改变它的值?

14 个答案:

答案 0 :(得分:31)

如果编译器知道值是常量且永远不会改变,它可以将值直接编译到程序中。

如果将pi声明为常量,则每次看到pi / 2时,编译器都可以执行计算并将1.57 ...直接插入到已编译的代码中。如果您将pi声明为变量,则每次程序使用pi / 2时,计算机都必须引用pi变量并将其乘以0.5,这显然较慢。

我还应该补充一点,C#有readonly,它适用于编译器无法计算的值,但在程序执行期间不能更改。例如,如果你想要一个常量ProgramStartTime,你必须声明它readonly DateTime ProgramStartTime = DateTime.Now,因为它必须在程序启动时进行评估。

最后,你可以通过给它一个getter而不是setter来创建一个只读属性,如下所示:

int Months { get { return 12; } }但作为一个属性,每次阅读时都不必具有相同的值,如下所示:

int DaysInFebruary { get { return IsLeapYear ? 29 : 28 } }

答案 1 :(得分:14)

当下列情况之一获得时,“不能改变”和“不会改变”之间的区别才真正变得明显:

  • 其他开发人员开始处理您的代码,
  • 第三方开始使用您的代码,或
  • 一年过去了,你回到那段代码。

谈论数据可访问性时会出现非常类似的问题。这个想法是你希望你的代码只提供你想要的灵活性,因为否则某人(可能是你)会出现并做你不想要的事情,这会导致错误!

答案 2 :(得分:7)

如果你永远不会犯错误,那么你工作的任何团队中的任何人都不会犯错误,你永远不会忘记你已经定义的变量的确切目的,即使在回到几个月或几年没看过的代码之后,并且你和你工作的每个人100%可靠地识别,理解并遵循你的意图,当你没有打扰使用内置的语言结构时,你永远不会改变const值,这种结构既清楚地表明并强制执行const,那么不,没有点。

如果其中任何一件事情都不是这样,那就是重点。

至于我,我发现,即使我最清醒,一次记住超过七件事几乎是不可能的,所以我会尽力帮助防止错误,特别是成本是一个关键字。如果你比我更聪明,而且你永远不必与一个不如你聪明的人一起工作,那么就做你想做的事。

在某些情况下,可能会有一些编译器优化可以基于constness(常量折叠,对于一个,在编译时折叠由常量组成的表达式)来完成。但通常情况下,这不是重点。

答案 3 :(得分:3)

请记住,您可能不是唯一使用该值的人。您不仅无法更改它,而且没有人使用您的代码(例如,作为库)可以更改它。

将其标记为常数也会使您的意图明确。

答案 4 :(得分:2)

就是这样。你告诉编译器它永远不会改变,编译器可以更好地优化,知道它是不可变的。

答案 5 :(得分:2)

使用常量程序员具有可读性优于实际值的优点,如

const double PI = 3.14159;

与变量相比,它还可以通过在编译时插入值而不是从寄存器/内存位置推断来加速计算。

答案 6 :(得分:1)

有几个原因:

  1. 您希望区分具有某些含义的某些值与其他变量。
  2. 您可能后来忘记了您不想改变价值,并导致不可预见的行为。
  3. 您的代码可能被其他人使用,他们可能会更改它(特别是如果您正在开发库或API)。
  4. 因为所有可能出错的事情通常会 - 所以通过在编译时而不是运行时发现这些错误来防止它。

答案 7 :(得分:1)

声明值'const'可以让编译器发挥作用,通过不允许对该值进行任何更改来帮助您强制执行个人约束。

此外,它会捕获意外错误,因为传递值(您打算将其视为常量)的副作用带入一个带有'ref'参数的方法,并且可以想象会意外地改变该值。

答案 8 :(得分:1)

严格来说,“const”不是必需的。例如,Python既没有“const”也没有“private”;使用THIS_IS_A_CONSTANT和_this_is_private的命名约定指定您的意图。

然而,C#的设计理念是在编译时而不是运行时捕获错误。

答案 9 :(得分:1)

关于可读性,程序员的不同语义是正确的,你应该知道所有这些。

但与普通变量相比,C#中的常量(相当于.net)具有非常不同的语义(在实现方面)。

因为常量值永远不会改变,所以常量被认为是其中的一部分 定义类型。换句话说,常量总是被认为是静态成员,而不是 实例成员。定义常量会导致元数据的创建。当代码引用常量符号时,编译器将该值嵌入到发出的中间语言(IL)代码中。

这些约束意味着常量没有良好的跨程序集版本控制故事,因此只有在知道符号的值永远不会改变时才应使用它们。

答案 10 :(得分:0)

“点”是这样的,你可以使用一个程序范围的变量,只有一个点来改变它。

想象一下,如果您制作的视频游戏依赖于100个不同代码文件中的FPS(每秒帧数)。所以假装FPS是50 ......并且你在所有这些文件和函数中都有“50”的数字......然后你意识到你想让它达到60 FPS ......而不是改变那100个文件,你会只是改变这个:

const int FRAMES_PER_SECOND = 60;

在这些文件/函数中,您将使用FRAMES_PER_SECOND变量。

顺便说一下,这与C#无关......常量有很多语言。

答案 11 :(得分:0)

这是明确你的意图的情况。

如果您打算更改值,请不要使用'const'。 如果您不打算更改值,请使用'const'。

这样编译器和第三方(或者你自己,如果你长时间阅读你的代码)可以知道你的意图。如果你或某人犯了改变值的错误,那么编译器就可以检测到它。

无论如何,使用'const'不是强制性的。如果你认为,你可以自己处理'恒定'(不希望编译器检测到错误),那么不要使用'const'; - )。

答案 12 :(得分:0)

当你知道它的值在你的应用程序中保持不变时,你应该将变量定义为“const”。因此,一旦定义了const,它的值必须在编译时可以确定,并且该值将保存到程序集的元数据中。一些更重要的观点:康斯特:

  1. 只能为编译器视为主要类型的类型定义const。
  2. 常量被视为定义类型的一部分。
  3. 他们一直被认为是静态成员。
  4. 常量值总是直接嵌入到代码中,因此常量不需要在运行时将任何内存分配给它们。
  5. 由于将值嵌入到元数据中,当有人因版本控制或其他一些要求而更改const的值(在定义const的程序集中)时 那么dll的用户必须重新编译自己的程序集。使用“readonly”关键字可以避免这个问题。

答案 13 :(得分:-1)

许多程序员遵循的规则之一是:永远不要硬编码任何变量/ 0除外。 这意味着,而不是做

for(int i=0; i<100; i++) {}

应该

const loopCount = 100;
....
for (int i=0; i<loopCount; i++) {}

我认为使用const是替换它的一个很好的理由。事实上,还有更多的理由:

  1. 优化编译器 - 内存,性能。
  2. 告诉程序员关注您的工作,这是CONSTANT
  3. 如果你需要重构,改变你的想法,你知道去哪里。并确保代码中没有其他地方可以改变这一点。