C#中损坏的string
我碰到“CorruptedString”(解决scheme) 。 以下是本书的程序代码:
var s = "Hello"; string.Intern(s); unsafe { fixed (char* c = s) for (int i = 0; i < s.Length; i++) c[i] = 'a'; } Console.WriteLine("Hello"); // Displays: "aaaaa" 为什么这个程序显示“aaaaa”? 我理解这个程序如下:
- CLR在实习生池中保留“hello”(我将实习生池形象为一组string)。
-   string.Intern(s)实际上什么都不做,因为CLR保留了“Hello”string – 它只是返回保留的“Hello”string的地址(对象s具有相同的地址)
- 该程序通过指针更改“Hello”string的内容
- ??? Hellostring应该在实习生池中不存在,应该是错误的! 但是没关系; 该程序运行成功。
据我了解实习生池,它就像某种string的字典串。 或者我错过了什么?
 当你第一次使用“Hello”的时候,它会被join到应用程序的全局string存储中。 根据你在unsafe模式下执行的事实(更多关于这里的 unsafe ),你可以直接引用存储在最初分配给strings值的位置的数据,所以通过 
 for (int i = 0; i < s.Length; i++) c[i] = 'a'; 
 你正在编辑内存中的内容。 当它下次访问internedstring的时候,它会在内存中使用相同的地址,保存你刚才改变的数据。 没有unsafe这是不可能的。 string.Intern(s); 在这里不起作用; 如果你注释掉它,它的行为是一样的。 
然后通过
 Console.WriteLine("Hello"); // Displays: "aaaaa" 
  .NET查看是否有一个地址为"Hello"获得的地址,并且有:您刚更新为"aaaaa" 。  'a'字符的数量由"Hello"的长度决定。 
 即使@Jaroslav Kadlec答案是正确和完整的我想添加一些关于代码的行为,为什么string.Intern(s);更多信息string.Intern(s); 在这种情况下是无用的。 
关于实习生池
实际上,.NET会自动执行string的所有stringinterning,这是通过使用一个特殊的表来存储对应用程序中所有唯一string的引用。
但是,重要的是要注意,只有显式声明的string在编译阶段被执行 。
考虑下面的代码:
 var first = "Hello"; //Will be interned var second = "World"; //Will be interned var third = first + second; //Will not be interned 
 当然,在某些情况下,我们希望在运行时实习一些string,这可以通过String.Intern进行检查后通过String.Intern来完成。 
所以回到OP的片段:
 //... var s = "Hello"; string.Intern(s); //... 
 在这种情况下string.Intern(s); 没有用,因为它已经在编译阶段实现了。