由于字符串是不可变的,具有相同字符串值的变量是否指向相同的字符串对象?

时间:2010-02-09 19:25:04

标签: c# .net string

A)

        string s  = "value";
        string s1 = "value";

s和s1引用变量是否指向同一个字符串对象(我假设这是因为字符串是不可变的)?

b)我意识到等式运算符(==,>等)已被重新定义以比较字符串对象的值,但在使用静态方法Object.Equals()和Object.ReferenceEquals(比较两个字符串)时是相同的。 )?

感谢名单

3 个答案:

答案 0 :(得分:21)

不,并非所有具有相同值的字符串都是相同的对象引用。

编译器生成的字符串都将被Interned并且是相同的引用。在运行时生成的字符串默认情况下不会被实现,并且将是不同的引用。

var s1 = "abc";
var s2 = "abc";
var s3 = String.Join("", new[] {"a", "b", "c"});
var s4 = string.Intern(s3); 
Console.WriteLine(ReferenceEquals(s1, s2)); // Returns True
Console.WriteLine(ReferenceEquals(s1, s3)); // Returns False
Console.WriteLine(s1 == s3); // Returns True
Console.WriteLine(ReferenceEquals(s1, s4)); // Returns True

注意上面的行,您可以使用String.Intern(string)强制字符串实现,然后允许您使用对象相等而不是字符串相等来进行某些检查,这要快得多。这是非常常用的一个示例是在生成的XML序列化程序代码中以及名称表。

答案 1 :(得分:3)

是的,这些将指向相同的字符串,因为它们都被定义为字符串文字。如果以编程方式创建字符串,则必须手动输入字符串。

这是因为.NET框架将程序中的字符串文字实习到实习池中。您可以使用String.Intern来检索此引用,或者手动实现您自己的运行时生成的字符串。

有关详细信息,请参阅docs for Intern

  

因此,具有特定值的文字字符串实例仅在系统中存在一次。

     

例如,如果将相同的文字字符串分配给多个变量,则运行时将从实习池中检索对文字字符串的相同引用,并将其分配给每个变量

答案 2 :(得分:2)

使用当前CLR相同的文字字符串确实指向相同的实际对象。该过程称为interning,适用于所有编译时字符串。

在运行时创建的字符串不会默认实现,但可以通过调用string.Intern添加到实习集合中。

有关.NET字符串存储方式的详细说明,请参阅my answer for this question