Kamerton Asked:2020-03-19 17:51:52 +0000 UTC2020-03-19 17:51:52 +0000 UTC 2020-03-19 17:51:52 +0000 UTC 为什么 System.String.Empty 不为空? 772 好的。 也许我的问题因为它的不正确而令人困惑,但这只是为了让你和我有同样的感觉。 我用两个反编译器(dotPeek 和 ILSpy)反编译了 mscorelib.dll v4.0,它们都向我展示了这是一个字段readonly,并且没有在类中初始化。类 NOT partial。 当然,执行时,一切都很好string.Empty is "",但是有人可以向我解释为什么会这样吗?如果不在这里(也找不到静态构造函数),那么该字段在哪里初始化?还是这些反编译器看不到东西? c# 1 个回答 Voted Best Answer VladD 2020-03-19T22:32:58Z2020-03-19T22:32:58Z 看,在初始化语言的基本部分时,有时你离不开魔法。 例如,您认为如何用 C# 结构来描述,例如int?该结构有一个隐藏字段m_value,例如... int!普通结构不会编译这个,但是编译器在编译这个类时知道它是一个内部类型,并以一种特殊的方式处理它。 当您使用string.Empty. 在 Microsoft 实现中,JIT 编译器知道什么string.Empty是特殊值并将其替换为常量。这是优化所必需的:该字段经常使用。 原则上,在这种情况下,可能永远不会初始化这个字段,但是反射和调试器会看到“错误”的值,这当然不好。为此,该字段仍然由运行时单独初始化,运行时也知道这种特殊情况。(为什么不通过静态构造函数?可以假设调用静态构造函数相对昂贵,因为它必须获取全局锁,以防同时在多个线程上调用静态构造函数。) 当然,所有这些都是当前版本的编译器和 Microsoft 运行时库实现的细节;在其他实现(例如 Mono)中,该特定位置可能没有任何魔法。 真理发现者的桂冠属于@Grundy,他“挖掘”了确切的原因并在评论中指出了这一点。
看,在初始化语言的基本部分时,有时你离不开魔法。
例如,您认为如何用 C# 结构来描述,例如
int?该结构有一个隐藏字段m_value,例如...int!普通结构不会编译这个,但是编译器在编译这个类时知道它是一个内部类型,并以一种特殊的方式处理它。当您使用
string.Empty. 在 Microsoft 实现中,JIT 编译器知道什么string.Empty是特殊值并将其替换为常量。这是优化所必需的:该字段经常使用。原则上,在这种情况下,可能永远不会初始化这个字段,但是反射和调试器会看到“错误”的值,这当然不好。为此,该字段仍然由运行时单独初始化,运行时也知道这种特殊情况。(为什么不通过静态构造函数?可以假设调用静态构造函数相对昂贵,因为它必须获取全局锁,以防同时在多个线程上调用静态构造函数。)
当然,所有这些都是当前版本的编译器和 Microsoft 运行时库实现的细节;在其他实现(例如 Mono)中,该特定位置可能没有任何魔法。
真理发现者的桂冠属于@Grundy,他“挖掘”了确切的原因并在评论中指出了这一点。