字符串常量在.net中嵌入了两次?常量、两次、字符串、net

由网友(鼻尖触碰)分享简介:说我有一个简单的(最简单?)C#程序:Say I have a simple (the simplest?) C# program:class Program {static void Main() {System.Console.WriteLine("Hello, world");}}如果,我编译code和看所...

说我有一个简单的(最简单?)C#程序:

Say I have a simple (the simplest?) C# program:

class Program {
    static void Main() {
      System.Console.WriteLine("Hello, world");
    }
}

如果,我编译code和看所产生的.exe文件,我看到你好,世界,在预期的exe文件图像的字符串。

If, I compile that code and look at the resultant .exe, I see the "Hello, world" string in the exe image as expected.

如果我重构code到:

If I refactor the code to:

class Program {
    const string Greeting = "Hello, world";
    static void Main() {
      System.Console.WriteLine(Greeting);
    }
}

如果我编译code和看所产生的.exe文件,我看到你好,世界字符串中的exe文件图像的两倍。这令我感到诧异。我下的是IM pression的字符串是共享的,而且会为此只有在图像一次显示出来。任何人都可以解释一下吗?也许串的第二个副本是需要反思的元数据?

If I compile that code and look at the resultant .exe, I see the "Hello, world" string literal in the exe image twice. This was surprising to me. I was under the impression that string literals were shared, and that it would therefor only show up in the image one time. Can anyone explain this? Perhaps this second copy of the string is needed for reflection metadata?

推荐答案

在 ECMA-335 CLI规范揭示了这方面的一些光。 C#常量被声明为在IL一静态文字字段。从第I.8.6.1.2(重点煤矿):

The ECMA-335 CLI specification sheds some light on this. A C# const is declared as a static literal field in IL. From section I.8.6.1.2 (emphasis mine):

在文字的约束承诺,该位置的值实际上是一个固定值   的内置类型。的值被指定为约束的一部分。 编译器是   需要替换其值的位置的所有引用,因此VES   不需要分配空间的位置。这个约束,而在逻辑适用于   任何位置,只能放在复合类型的静态字段。 字段是   所以明显是不允许从CIL引用(它们应以内衬其   在编译时的固定值),但可用的使用反射和工具   直接处理元数据。

The literal constraint promises that the value of the location is actually a fixed value of a built-in type. The value is specified as part of the constraint. Compilers are required to replace all references to the location with its value, and the VES therefore need not allocate space for the location. This constraint, while logically applicable to any location, shall only be placed on static fields of compound types. Fields that are so marked are not permitted to be referenced from CIL (they shall be in-lined to their constant value at compile time), but are available using reflection and tools that directly deal with the metadata.

因此​​,编译器会不断的价值和整个code替换它。它不允许引用常数存储。它从那里是什么,是做什么的其他任何文字字符串。这使得它在元数据表中的插槽,并使用 ldstr 运算code加载字符串。因此,值在汇编中出现两次。一旦为常数,它不能由一个兼容的编译器中引用的存储位置。另一次在你的元数据表。

Thus the compiler takes the constant value and replaces it throughout the code. It is not allowed to reference the constant storage. What it does from there, is what it does for any other literal string. It gives it a slot in the metadata table and uses the ldstr op code to load the string. Thus, the value appears twice in your assembly. Once in the storage location for the constant, which cannot be referenced by a compliant compiler. And another time in your metadata table.

阅读全文

相关推荐

最新文章