在C#中,字符串被实现.也就是说,如果我创建字符串foobar
并再次使用它,C#将只在内存中有一个字符串实例,虽然我将有两个引用,但它们都将指向同一个字符串实例.这就是为什么字符串必须在C#中不可变的一个原因.
现在,我的问题是,是否有可能以某种方式创建两个相同的字符串,以便它们不被实现,但我们最终在内存中有两个不同的字符串实例,有两个不同的地址,包含相同的文本?
如果是这样,怎么样?
而且,这是不是偶然发生的事情,或者您是否需要为此案例明确构建场景?
并且,最后:假设在内存中有两个单独的字符串实例具有相同的值,它们是否相等(就其而言==
)?如果是这样,怎么==
工作?首先通过参考比较,然后按值,或......?
在C#中,字符串被实现.
不可以.在C#中允许使用字符串.这是一个非常不同的声明.
也就是说,如果我创建字符串foobar并再次使用它,C#将只在内存中有一个字符串实例,虽然我将有两个引用,但它们都将指向同一个字符串实例
不可以.再次,在C#中,允许运行时决定一个"foobar"与另一个"foobar"相同并实习它们,但不需要这样做.
当然,如果复制引用,则复制引用.但是,如果您创建第二个与早期字符串相同的字符串,则不需要对其进行实习.
在实践中,字符串在文字时被加密:
string x = "foobar"; string y = "foobar"; // x is reference equal to y
或者当编译器可以将它们计算为相同时:
string x = "foobar"; string y = "foo" + "bar"; // x is reference equal to y
或者,当您明确告诉运行时您要实例化特定字符串时.否则字符串通常不会被实现:
string x = "foobar"; string y = "f" + x.Substring(1); // x and y are not reference equal
仅限字符串文字.运行时实习是昂贵的,因此动态创建的字符串不会被实现(除非您通过调用显式实现它们String.Intern
).
以下字符串都是不同的实例(您可以使用它来检查object.ReferenceEquals()
):
string str1 = "foo"; string str2 = "FOO".ToLower(); string str3 = new StringBuilder().Append("f").Append("oo").ToString();
该==
操作符被重载为string
他们按值参考比较,不
public static bool operator == (String a, String b) { return String.Equals(a, b); }
使用==
运算符时,您必须记住运算符不是多态的.因此,如果两个操作数的编译时类型都是string
,string
则将使用重载.如果它们中的至少一个是object
,则将执行参考比较
string str1 = "foo"; string str2 = "FOO".ToLower(); object str3 = str2; bool valueComparison = str1 == str2; // true - the same value bool referenceComparison = str1 == str3; // false - different instances