下面是个人的练习:


//
字符串拘留练习 by mcjeremy
// 声明s1时,拘留池中没有该字符串,因此将它放进去
// 放进去后,string.IsIntered(s1),将返回该字符串值
string s1 = " abc123 " ;
// 声明s2时,由于拘留池中已经有该字符串存在,因此不再分配内存
// s2和s1将指向同一个引用
string s2 = " abc123 " ;
// s3背后实际调用的是concat,因此,它是动态创建的。
// 因此,会分配新的内存
string s3 = s1 + s2;
// 创建s4时,编译器会优化它,背后调用的是ldstr,因此,会发现拘留池中已经
// 有abc123,因此不再分配内存,此时 s1,s2,s4都指向同一个引用
string s4 = " abc " + " 123 " ;
string s5 = " 123 " ;
// 创建s6时,背后实际调用的是concat,因此,它是动态创建的。
// 因此,会分配新的内存
string s6 = " abc " + s5;
Console.WriteLine(Object.ReferenceEquals(s1, s2)); // true
Console.WriteLine(Object.ReferenceEquals(s1, s3)); // false
Console.WriteLine(Object.ReferenceEquals(s1, s4)); // true
Console.WriteLine(Object.ReferenceEquals(s1,s6)); // false
Console.WriteLine( string .IsInterned(s3) ?? " Null " ); // null
Console.WriteLine( string .IsInterned(s1) ?? " Null " ); // abc123
Console.WriteLine( string .IsInterned(s6) ?? " Null " ); // abc123
// 声明s1时,拘留池中没有该字符串,因此将它放进去
// 放进去后,string.IsIntered(s1),将返回该字符串值
string s1 = " abc123 " ;
// 声明s2时,由于拘留池中已经有该字符串存在,因此不再分配内存
// s2和s1将指向同一个引用
string s2 = " abc123 " ;
// s3背后实际调用的是concat,因此,它是动态创建的。
// 因此,会分配新的内存
string s3 = s1 + s2;
// 创建s4时,编译器会优化它,背后调用的是ldstr,因此,会发现拘留池中已经
// 有abc123,因此不再分配内存,此时 s1,s2,s4都指向同一个引用
string s4 = " abc " + " 123 " ;
string s5 = " 123 " ;
// 创建s6时,背后实际调用的是concat,因此,它是动态创建的。
// 因此,会分配新的内存
string s6 = " abc " + s5;
Console.WriteLine(Object.ReferenceEquals(s1, s2)); // true
Console.WriteLine(Object.ReferenceEquals(s1, s3)); // false
Console.WriteLine(Object.ReferenceEquals(s1, s4)); // true
Console.WriteLine(Object.ReferenceEquals(s1,s6)); // false
Console.WriteLine( string .IsInterned(s3) ?? " Null " ); // null
Console.WriteLine( string .IsInterned(s1) ?? " Null " ); // abc123
Console.WriteLine( string .IsInterned(s6) ?? " Null " ); // abc123