6

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

4

3 回答 3

7

The documentation states that the attribute:

Marks an assembly as not requiring string-literal interning.

In other words, it does not prevent the compiler from doing string interning, just providing a hint that it is not required. The documentation is a little bit sparse in this area, but this also seems to be the conclusion in this MSDN forum post.

于 2013-03-24T18:01:00.627 回答
5

不是踢开的门,但显然该属性不会像您认为的那样起作用。在 MSDN 和 CLI 规范中,它的文档都很差。从它在 CLR 中的使用对我来说唯一明显的是,当它打开时,编译器只需要确保在模块级别内嵌相同的字符串。这有许多与内联、ngen-ed 和混合模式程序集相关的副作用。

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

于 2013-03-24T18:45:59.380 回答
0

NoStringInterning 的 MSDN 描述说

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

说程序集不需要实习与说应该关闭该功能是不同的。AFAIK 没有办法做到这一点(NGEN 除外)。

于 2013-03-24T17:59:29.247 回答