C#中的“常量字符串”与“静态只读字符串”


Answers:


170

当您使用一个const字符串,编译器嵌入字符串的值在编译时
因此,如果const在其他程序集中使用一个值,然后更新原始程序集并更改该值,则另一个程序集将在您重新编译之前看不到更改它。

一个static readonly字符串是都在运行时抬头正常现场。因此,如果在其他程序集中更改了字段的值,则在程序集加载后即会看到更改,而无需重新编译。

这也意味着static readonly字符串可以使用非常量成员,例如Environment.UserNameDateTime.Now.ToString()。一个const字符串,只能使用其他常量或文字进行初始化。
另外,static readonly可以在静态构造函数中设置字符串。一个const字符串只能是初始化内联。

请注意,static string可以修改;您应该static readonly改用。


25
+1,而明显的结论,从实际和语义点的观点:const应仅用于常量-常量在于值永远永远永远改变。
路加福音2010年

3
@LukeH 永无止境,永无止境。我想不到如果将一个私有字符串声明为const并在两个重新编译事件之间更改它,将会发生任何不好的事情。
布伦达·贝尔

5
@Brenda:我承认我确实使用private const了严格来说不是常量的值;基本上,它被滥用const于微优化目的。我将坚持我的“永无止境”声明,即使这使我成为伪君子。;)
LukeH 2012年

如果是字符串,性能如何?每个const用法都会在内存中产生一个新的字符串副本吗?
Andrii

@Andrii不,常量字符串仅创建一次。每种用法在内存中都有相同的引用。
米格

43

这是优点和缺点的良好分类

因此,似乎应该在不太可能更改该值或没有外部应用程序/库使用该常量的情况下使用常量。当需要运行时计算或外部使用者是一个因素时,应使用静态只读字段。


19
文章中非常有趣的一点-“在较高层次上,常量显然是在编译时处理的,而静态只读字段是在运行时求值时设置的。常量值由编译器代替的事实意味着如果常量值发生更改,则引用常量值的任何库/程序集都需要重新编译;引用静态只读字段的库将引用该字段,而不是值,因此它们将在不需要该字段的情况下进行任何更改进行重新编译”
s_hewitt,2010年

1
是的,我也读了,很开心。我绝对不知道。
spinon'7

:这是谷歌的缓存版本webcache.googleusercontent.com/...
自旋子

2
参考链接不再可用。
所罗门·张

这是对标记为解决方案的答案的很好补充。定义用法非常有帮助。向我+1。
Bonez024

11

const

public const string MyStr;

是一个编译时间常数(例如,您可以将其用作方法参数的默认参数),并且如果使用此类技术,则不会混淆

static readonly

public static readonly string MyStr;

运行时常量。这意味着它是在启动应用程序时而不是在启动之前进行评估的。这就是为什么不能将其用作方法的默认参数(例如编译错误)的原因。可以混淆其中存储的值。


6

OQ被问及static stringVS const。两者都有不同的用例(尽管都被视为静态)。

仅将const用于真正恒定的值(例如光速-但这甚至取决于介质而变化)。制定此严格指南的原因是,将const值替换为引用它的程序集中const的用法,这意味着如果const更改其定义位置(即,它不应该是一个常量),则可能会出现版本问题。毕竟)。请注意,这甚至会影响private const字段,因为您可能在不同的程序集中具有基类和子类,并且私有字段是继承的

静态字段与它们在其中声明的类型相关。它们用于表示对于给定类型的所有实例都必须相同的值。可以将这些字段写入任意多次(除非指定了只读)。

如果您的意思是static readonlyvs const,那么我建议static readonly在几乎所有情况下都使用它,因为它可以为以后提供更多证据。


您说的这个“ OQ”是谁?
Peter Mortensen

“原始问题”
Ben Aston

0

static readonly string只能在static类的构造函数或变量初始值设定项中更改a的值,而不能在const任何地方更改字符串的值。


2
除了现有答案已经说过的话,我看不出这会如何添加任何内容。
基金莫妮卡的诉讼
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.