我想知道特定于.Net框架的字符串实习的过程和内部.还想知道使用实习的好处以及我们应该使用字符串实习来提高性能的场景/情况.虽然我已经从Jeffery Richter的CLR书中学习实习,但我仍然感到困惑,并希望更详细地了解它.
[编辑]使用示例代码询问具体问题如下:
private void MethodA()
{
string s = "String"; // line 1 - interned literal as explained in the answer
//s.intern(); // line 2 - what would happen in line 3 if we uncomment this line, will it make any difference?
}
private bool MethodB(string compareThis)
{
if (compareThis == "String") // line 3 - will this line use interning (with and without uncommenting line 2 above)?
{
return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud) 在C#中,字符串被实现.也就是说,如果我创建字符串foobar并再次使用它,C#将只在内存中有一个字符串实例,虽然我将有两个引用,但它们都将指向同一个字符串实例.这就是为什么字符串必须在C#中不可变的一个原因.
现在,我的问题是,是否有可能以某种方式创建两个相同的字符串,以便它们不被实现,但我们最终在内存中有两个不同的字符串实例,有两个不同的地址,包含相同的文本?
如果是这样,怎么样?
而且,这是不是偶然发生的事情,或者您是否需要为此案例明确构建场景?
并且,最后:假设在内存中有两个单独的字符串实例具有相同的值,它们是否相等(就其而言==)?如果是这样,怎么==工作?首先通过参考比较,然后按值,或......?
例如:
public string ReplaceXYZ(string text)
{
string replacedText = text;
replacedText = replacedText.Replace("X", String.Empty);
replacedText = replacedText.Replace("Y", String.Empty);
replacedText = replacedText.Replace("Z", String.Empty);
return replacedText;
}
Run Code Online (Sandbox Code Playgroud)
如果我甚至为不包含"X","Y"或"Z"的字符串调用"ReplaceXYZ",每次会创建3个新字符串吗?
我在其中一个项目中发现了与此类似的代码.它被重复调用,因为它循环遍历大量字符串.
在下面的代码中,我正在检查对象引用的相等性.
string x = "Some Text";
string y = "Some Other Text";
string z = "Some Text";
Console.WriteLine(object.ReferenceEquals(x, y)); // False
Console.WriteLine(object.ReferenceEquals(x, z)); // True
Console.WriteLine(object.ReferenceEquals(y, z)); // False
y = "Some Text";
Console.WriteLine(object.ReferenceEquals(x, y)); // True
Console.WriteLine(object.ReferenceEquals(x, z)); // True
Console.WriteLine(object.ReferenceEquals(y, z)); // True
Run Code Online (Sandbox Code Playgroud)
这里:
x并z指同一个对象; 我可以说x是实习并z使用了taht版本.好吧,我不确定这个; 如果我错了,请纠正我.y通过赋予它与x相同的值来改变它的值.我以为它会在这里创建一个新对象; 但我错了,它使用相同的参考.我的问题是:
.net使用字符串实习生?我不明白:
MSDN说
http://msdn.microsoft.com/en-us/library/system.string.intern.aspx
因此,具有特定值的文字字符串实例仅在系统中存在一次.
例如,如果将相同的文字字符串分配给多个变量,则运行时将从实习池中检索对文字字符串的相同引用,并将其分配给每个变量.
这种行为是默认的(没有实习生)吗?或者使用Intern方法?
如果是默认值,为什么我要使用实习生?(实例将一次......)?
如果它是NOT默认值:如果我写了1000次这一行:
Console.WriteLine( "LALALA");
1)我会在记忆中得到1000次"lalala"吗?(不使用实习生...)
2)将"lalala"最终Gc'ed?
3)"lalala"是否已被实习?如果确实如此,为什么我需要从池中"获取"它,而不是再次写"lalala"?
我有点困惑.
string s1 = "test";
string s5 = s1.Substring(0, 3)+"t";
string s6 = s1.Substring(0,4)+"";
Console.WriteLine("{0} ", object.ReferenceEquals(s1, s5)); //False
Console.WriteLine("{0} ", object.ReferenceEquals(s1, s6)); //True
Run Code Online (Sandbox Code Playgroud)
字符串s5和s6都具有与s1相同的值("test").基于字符串实习概念,这两个语句必须已评估为true.有人可以解释为什么s5没有与s1相同的参考?