CompilationRelaxations.NoStringInterning实际上如何工作?

时间:2013-03-24 17:50:02

标签: c# string-interning

我在演示NoStringInterning时遇到问题

[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 ..作为输出,我得到的是一堆True。我期待一堆错误!

3 个答案:

答案 0 :(得分:5)

documentation表示属性:

  

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

换句话说,它不会阻止编译器进行字符串实习,只是提供一个不需要它的提示。这方面的文档有点稀疏,但这似乎也是this MSDN forum post中的结论。

答案 1 :(得分:5)

没有打开一扇门,但显然该属性没有按照你的想法行事。在MSDN和CLI规范中,它的文档都很差。在CLR中使用它对我来说唯一明显的一点是,当它打开时,编译器只需要确保在模块级别实现相同的字符串。这有许多副作用,与内联,代数和混合模式组件相关。

这将迫使我解释模块和组件之间的确切区别。我不能,模块是奇怪的野兽,在常见的.NET编程中没有实际用途。最好忘记这个属性是相关的。除非您有一个使用/ target:module选项运行C#编译器的自定义构建系统,否则C#编译器始终在程序集级别进行实习,因此您的测试将始终生成“true”。

答案 2 :(得分:0)

NoStringInterning的MSDN描述

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

说装配体不需要实习并不等于应该关闭该功能。 AFAIK没有办法做到这一点(NGEN除外)。