我试图理解为什么string.Empty是readonly而不是const。我看到了这邮报,但我不明白微软所写的评论。正如乔恩·斯基特( Jon 写 )在一条评论中所说的“我不知道--老实说,这对我来说没有多大意义……”
共享源公共语言基础设施2.0版。string.cs在sscli20\clr\src\bcl\system\string.cs
// The Empty constant holds the empty string value.
//We need to call the String constructor so that the compiler doesn't mark this as a literal.
//Marking this as a literal would mean that it doesn't show up as a field which we can access
//from native.
public static readonly String Empty = ""; 我在这里看不到任何字符串构造函数调用,而且它被标记为文字- ""。
请有人用纯文本解释我,这句话意味着什么?为什么string.Empty readonly而不是const?
更新:
我在午餐时询问了C#的一位老员工,他并没有特别记得为什么会做出这一决定,但猜测这与实习有关。
发布于 2011-12-18 17:27:21
重要的部分不是这个类中发生了什么,而是当另一个类使用(并链接到)它时会发生什么。让我用另一个例子来解释:
假设您有一个Assembly1.dll,其中包含一个类声明
public static const int SOME_ERROR_CODE=0x10;
public static readonly int SOME_OTHER_ERROR_CODE=0x20;而另一个类则在使用这个。
public int TryFoo() {
try {foo();}
catch (InvalidParameterException) {return SOME_ERROR_CODE;}
catch (Exception) { return SOME_OTHER_ERROR_CODE;}
return 0x00;
}您将类编译到Assembly2.dll中,并将其链接到Assembly1.dll,如预期的那样,您的方法将在无效参数上返回0x10,对其他错误返回0x20,在成功时返回0x00。
特别是,如果您创建Assembly3.exe包含以下内容
int errorcode=TryFoo();
if (errorcode==SOME_ERROR_CODE) bar();
else if (errorcode==SOME_OTHER_ERROR_CODE) baz();它将按预期工作(在与Assembly1.dll和Assembly2.dll链接之后)
现在,如果您获得Assembly1.dll的新版本,那么
public const int SOME_ERROR_CODE=0x11;
public readonly int SOME_OTHER_ERROR_CODE=0x21;如果您重新编译Assembly3.exe并将最后一个片段链接到新的Assembly1.dll和未更改的Assembly2.dll,它将停止正常工作:
bar()将不能正确调用: Assembly2.dll会记住文字0x20,这与Assembly3.exe从Assembly1.dll读取的文本0x21不同。
baz()将被正确调用: Assembly2.dll和Assembly3.exe都引用名为SOME_OTHER_ERROR_CODE的符号引用,在这两种情况下,这两种情况都由Assembly1.dll的当前版本解决,因此在这两种情况下都是0x21。
简而言之:const创建LITERAL,readonly创建SYMBOL REFERENCE。
LITERALS是框架内部的,不能封送,因此本机代码不能使用。
所以
public static readonly String Empty = ""; 创建一个symbol reference (在第一次使用时通过调用字符串cosntuctor重新定位),它可以封送因此从本机使用的
public static const String Empty = ""; 会创造一个文字,那是不可能的。
https://stackoverflow.com/questions/8485515
复制相似问题