大家都知道,C#中的string是一个引用类型,String对象是存放在堆上,而不是堆栈上的,因此,当把一个字符串变量赋给另一个字符串时,会得到对内存中同一个字符串的两个引用。但是大家有没有想过,为什么修改其中一个字符串,另外一个不受影响呢?
原来,当我们把一个字符串变量赋给另一个字符串时,就会创建一个全新的String对象,就是说这个时候就会有两个对象,比如:
class StringExc
{
public static void Main()
{
string s1 = "original string";
string s2 = s1; //注意此时会创建一个新对象
Console.WriteLine( "s1 is " + s1 );
Console.WriteLine( "s2 is " + s2 );
s1 = "changed string";
Console.WriteLine( "s1 is now " + s1 );
Console.WriteLine( "s2 is now " + s2 );
}
}
输出结果为:
s1 is original string
s2 is original string
s1 is now changed string
s2 is now original string
也就是说,改变s1的值并没有对s2造成任何影响,这与我们平时所说的引用类型的行为正好相反。当用值"original string"初始化s1时,就在堆上分配了一个String对象。在初始化s2时,引用也指向这个对象,所以s2的值也是"original string"。但是现在要改变s1的值,而不是替换原来的值时,堆上就会为新值分配一个新对象。s2变量仍然指向原来的对象,所以它的值没有改变。
另外,如果我们像下面这样:
string str1 = "abc";
string str2 = "abc";
当我们用System.Object.Equals(str1,str2)比较时,返回值是true;按理说str1和str2应该指向不同的空间,应该返回false才对啊。原来Equals有三个版本:
public override bool Equals(object);
public bool Equals(string);
public static bool Equals(string, string);