任何人都能说出C#中常量的含义是什么?
例如,做
的优点是什么const int months = 12;
而不是
int months = 12;
我知道常量不能改变,但为什么不只是......在初始化之后不改变它的值?
答案 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)
有几个原因:
答案 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,它的值必须在编译时可以确定,并且该值将保存到程序集的元数据中。一些更重要的观点:康斯特:
由于将值嵌入到元数据中,当有人因版本控制或其他一些要求而更改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是替换它的一个很好的理由。事实上,还有更多的理由: