两个相同的字符串可以是C#中的两个独立实例吗?

在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 

这是一个非常简单的测试,certificate2个等效的字符串并不总是指向同一个对象引用:

 static void Main(string[] args) { string str1 = "foo"; string str2 = "f"; str2 += "oo"; Console.WriteLine(str1 == str2); // prints true (value equality check) Console.WriteLine(object.ReferenceEquals(str1, str2)); // prints false (reference equality check) }