“string.Empty”上面令人困惑的注释的含义在.NET/BCL 源中?

发布于 2024-12-21 01:27:06 字数 1294 浏览 1 评论 0原文

我试图理解为什么 string.Emptyreadonly 而不是 const。我看到了这篇帖子,但我不明白微软对此的评论。正如 Jon Skeet 在评论中写道“我不知道 - 这对我来说没有多大意义,说实话......”

共享源公共语言基础结构 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 构造函数调用,此外,它被标记为文字 - ""

有人可以解释一下吗在纯文本中,注释是什么意思以及为什么是 string.Empty readonly 而不是 const


更新:
Eric Lippert 现已评论了 已删除的答案

我在午餐时向一位 C# 老前辈询问了此事,他并没有具体回忆起为什么做出这个决定,但推测这与实习有关。

I'm trying to understand why string.Empty is readonly and not a const. I saw this Post but I don't understand the comment Microsoft wrote about it. As Jon Skeet wrote in a comment "I don't know - it doesn't make much sense to me, to be honest..."

Shared Source Common Language Infrastructure 2.0 Release. string.cs is in 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 = ""; 

I can't see here any String constructor call and furthermore, it's marked as literal - ""

Can someone please explain me in plain text, What does the comment mean and why is string.Empty readonly and not a const?


Update:
Eric Lippert commented on by now a deleted answer:

I asked one of the C# old-timers over lunch about this and he did not recall specifically why this decision was made, but conjectured that it had something to do with interning.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

罪#恶を代价 2024-12-28 01:27:06

重要的部分不是这个类中发生了什么,而是当另一个类使用(并链接到)它时会发生什么。让我用另一个例子来解释:

假设您有一个 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

baz() 中读取的 0x21 将被正确调用:Assembly2.dll 和 Assembly3.exe 均引用名为 SOME_OTHER_ERROR_CODE 的符号引用,这两种情况均由当前版本的 Assembly1.dll 解析,因此这两种情况都是 0x21。

简而言之:const 创建一个LITERAL,一个readonly 创建一个SYMBOL REFERENCE

LITERALS 是框架内部的,无法编组并因此由本机代码使用。

因此,

public static readonly String Empty = ""; 

创建一个符号引用(在首次使用时通过调用 String cosntuctor 进行解析),可以对其进行编组,从而从本机使用,而

public static const String Empty = ""; 

会创建一个文字,但不能。

The important part is not what happens IN this class, but what happens, when another class uses (and links to) it. Let me explain with another example:

Assume you have a Assembly1.dll containing a class declaring

public static const int SOME_ERROR_CODE=0x10;
public static readonly int SOME_OTHER_ERROR_CODE=0x20;

and another class consuming this e.g.

public int TryFoo() {
    try {foo();}
    catch (InvalidParameterException) {return SOME_ERROR_CODE;}
    catch (Exception) { return SOME_OTHER_ERROR_CODE;}
    return 0x00;
}

You compile your class into Assembly2.dll and link it against Assembly1.dll, as expected, your method will return 0x10 on invalid parameters, 0x20 on other errors, 0x00 on success.

Especially, if you create Assembly3.exe containing something like

int errorcode=TryFoo();
if (errorcode==SOME_ERROR_CODE) bar();
else if (errorcode==SOME_OTHER_ERROR_CODE) baz();

It will work as expected (After being linked against Assembly1.dll and Assembly2.dll)

Now if you get a new version of Assembly1.dll, that has

public const int SOME_ERROR_CODE=0x11;
public readonly int SOME_OTHER_ERROR_CODE=0x21;

If you recompile Assembly3.exe and link the last fragment against new Assembly1.dll and unchanged Assembly2.dll, it will stop working as expected:

bar() will NOT be called correctly: Assembly2.dll remembers the LITERAL 0x20, which is not the same literal 0x21 that Assembly3.exe reads out of Assembly1.dll

baz() will be called correctly: Both Assembly2.dll and Assembly3.exe refer to the SYMBOL REFERENCE called SOME_OTHER_ERROR_CODE, which is in both cases resolved by the current version of Assembly1.dll, thus in both cases is 0x21.

In Short: a const creates a LITERAL, a readonly creates a SYMBOL REFERENCE.

LITERALS are internal to the framework and can not be marshalled and thus used by native code.

So

public static readonly String Empty = ""; 

creates a symbol reference (resovled at time of first use by a call to the String cosntuctor), that can be marshalled an thus used from native, while

public static const String Empty = ""; 

would create a literal, that can't.

两相知 2024-12-28 01:27:06

这并没有直接回答原因,但它提供了一些额外的背景信息。 String.Empty 被运行时和 JIT 视为固有的。它的工作原理与下面的 "" 完全相同。两者都会为您提供指向空字符串单例的指针,并且 JIT 代码对于两者来说看起来也相同。您使用哪一种只是一种风格问题。此外,内存分配没有区别。

This doesn't directly answer the why but it gives some additional context. String.Empty is treated as intrinsic by the runtime and the JIT. It works exactly same as "" underneath. Both will give you pointer to the empty string singleton and the JITed code will look same for both as well. It is just a style matter which one you use. Furthermore, there is no difference in memory allocation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文