CompilationRelaxations.nostringintern实际上是有效的

本文关键字:有效 实际上 nostringintern CompilationRelaxations | 更新日期: 2023-09-27 18:05:39

我在演示nostringintern时遇到问题

[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。我期待一堆假!

CompilationRelaxations.nostringintern实际上是有效的

文档声明属性:

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

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

不是踢开了一扇门,但很明显,这个属性并没有像你想象的那样起作用。在MSDN和CLI规范中,它的文档都很差。对我来说,从它在CLR中的使用中唯一明显的是,当它被打开时,编译器只需要确保相同的字符串在模块级别被嵌入。这有许多与内联、生成和混合模式程序集相关的副作用。

这将迫使我解释模块和程序集之间的确切区别。模块是一种奇怪的东西,在一般的。net编程中没有实际用途。最好完全忘记这个属性是相关的。除非你有一个使用/target:module选项运行c#编译器的自定义构建系统,否则c#编译器总是在汇编级实习,所以你的测试总是产生"true"。

nostringintern的MSDN描述为

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

说程序集不需要实习并不等于说应该关闭该功能。恐怕没有办法做到这一点(除了NGEN)。