我在演示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。我期待一堆错误!
答案 0 :(得分:5)
documentation表示属性:
将程序集标记为不需要字符串文字实习。
换句话说,它不会阻止编译器进行字符串实习,只是提供一个不需要它的提示。这方面的文档有点稀疏,但这似乎也是this MSDN forum post中的结论。
答案 1 :(得分:5)
没有打开一扇门,但显然该属性没有按照你的想法行事。在MSDN和CLI规范中,它的文档都很差。在CLR中使用它对我来说唯一明显的一点是,当它打开时,编译器只需要确保在模块级别实现相同的字符串。这有许多副作用,与内联,代数和混合模式组件相关。
这将迫使我解释模块和组件之间的确切区别。我不能,模块是奇怪的野兽,在常见的.NET编程中没有实际用途。最好忘记这个属性是相关的。除非您有一个使用/ target:module选项运行C#编译器的自定义构建系统,否则C#编译器始终在程序集级别进行实习,因此您的测试将始终生成“true”。
答案 2 :(得分:0)
NoStringInterning的MSDN描述
“将程序集标记为不需要字符串文字实习。”
说装配体不需要实习并不等于应该关闭该功能。 AFAIK没有办法做到这一点(NGEN除外)。