【发布时间】:2015-06-15 06:02:31
【问题描述】:
在 C# 中,字符串是不可变的和托管的。从理论上讲,这意味着任何字符串A 和B 的连接都会导致分配一个新的缓冲区,但这一切都非常模糊。当您与标识(空字符串)连接时,引用保持不变。这是编译时优化还是重载赋值运算符决定在运行时不重新分配?此外,当我修改s1 的值时,运行时/编译器如何处理s2 的值/分配?我的程序将表明s1 的原始地址处的内存保持不变(s2 继续指向那里),而新值发生 relloc,然后s1 指向那里,这是对什么的准确描述发生在幕后?
示例程序;
static void Main(string[] args)
{
string s1 = "Some random text I chose";
string s2 = s1;
string s3 = s2;
Console.WriteLine(Object.ReferenceEquals(s1, s2)); // true
s1 = s1 + "";
Console.WriteLine(Object.ReferenceEquals(s1, s2)); // true
Console.WriteLine(s2);
s1 = s1 + " something else";
Console.WriteLine(Object.ReferenceEquals(s1, s2)); // false cause s1 got realloc'd
Console.WriteLine(Object.ReferenceEquals(s2, s3));
Console.WriteLine(s2);
Console.ReadKey();
}
【问题讨论】:
-
别忘了还有字符串实习可以加入其中:-)
-
您的问题到底是什么?这些只是对一种简单优化的一些观察。对于 s1/s2 混淆,请查找有关引用类型的教程。一张有图片。
s1不是string -
添加这个:
Object.ReferenceEquals("Hi Evan", "Hi Evan");看看结果如何。 -
@HenkHolterman 主要问题是导致该行为的优化是什么?它发生在运行时还是编译时?
-
@Cameron 好吧,是的,我认为
s2到s3的比较表明所有字符串都已被保留,s1曾经指向那里,但现在不再指向那里。