C# CompliationRelaxations.NoStringInterning实际上是如何工作的?

C# CompliationRelaxations.NoStringInterning实际上是如何工作的?,c#,string-interning,C#,String Interning,我在实习时遇到问题 [assembly: System.Runtime.CompilerServices.CompilationRelaxations(System.Runtime.CompilerServices.CompilationRelaxations.NoStringInterning)] class Program { static void Main(string[] args) { String s1 =

我在实习时遇到问题

[assembly: System.Runtime.CompilerServices.CompilationRelaxations(System.Runtime.CompilerServices.CompilationRelaxations.NoStringInterning)]

    class Program
    {
        static void Main(string[] args)
        {
            String s1 = "Friday";
            String s2 = "Friday";
            String s3 = "Friday";
            String s4 = "Friday";
            String s5 = "Friday";
            String s6 = "Friday";
            String s7 = "Friday";
            String s8 = "Friday";
            String s9 = "Friday";
            // etc...
            Console.WriteLine(Object.ReferenceEquals(s1, s2));
            Console.WriteLine(Object.ReferenceEquals(s1, s3));
            Console.WriteLine(Object.ReferenceEquals(s1, s4));
            Console.WriteLine(Object.ReferenceEquals(s1, s5));
            Console.WriteLine(Object.ReferenceEquals(s1, s6));
            Console.WriteLine(Object.ReferenceEquals(s1, s7));
            Console.WriteLine(Object.ReferenceEquals(s1, s8));
            Console.WriteLine(Object.ReferenceEquals(s1, s9));
            // etc...

我已尝试使用.NET CLR 2、3、4。。作为输出,我得到的是一堆真的。我期待着一堆假的

MSDN对NoStringInterning的描述是

“将程序集标记为不需要字符串文字实习。”

说部件不需要实习与说特征应该关闭并不相同。恐怕没有办法做到这一点(NGEN除外)。

该属性声明:

将程序集标记为不需要字符串文字插入


换句话说,它并不阻止编译器进行字符串内部处理,只是提供了一个提示,表明它不是必需的。这方面的文档有点少,但这似乎也是中的结论。

没有打开门,但很明显,该属性并不像您认为的那样。在MSDN和CLI规范中,它的文档都非常糟糕。从CLR中使用它的情况来看,我唯一清楚的是,当它打开时,编译器只需确保在模块级别插入相同的字符串。这有许多与内联、ngen ed和混合模式组件相关的副作用


这将迫使我解释模块和程序集之间的确切区别。我不能,模块是奇怪的野兽,在普通的.NET编程中没有实际用途。最好忘记这个属性是相关的。除非你有一个定制的编译系统运行带有/target:module选项的C#编译器,否则C#编译器总是在汇编级别实习,所以你的测试总是会生成“true”。

driis,如果我在编译后查看IL DASM,我会看到一堆带有ldstr“Friday”的行。您编写了“不阻止编译器进行字符串内部处理”这与编译器有什么关系?如果编译器正在实习,那么方法中不应该只有一个ldstr“星期五”吗?为什么我必须要付出代价,加载这个常量很多次,并让运行时来整理重复的内容?我很困惑…我不认为ILDASM给了你全部的故事。可能该字符串在#US堆中只存在一次,并且CLR在#US堆中为每个字符串实例化一个字符串对象(而不是为每个唯一的字符序列实例化一个对象,该字符串具有正常的字符串插入)。由于ILDASM将#US堆引用替换为实际的字符串文本,因此我认为您需要使用一些较低级别的工具来查看其中的实际内容。