我是C#字符串的新手,对此我感到困惑
Object.referenceEquals
我正在阅读一篇文章,指出ReferenceEquals
是否在程序中是否与实例相同?我正在检查object.ReferenceEquals(s1, s4)
是否为同一个数据,即使它们指向相同的数据,为什么它也为false?
string s1 = "akhil";
string s2 = "akhil";
Console.WriteLine(object.ReferenceEquals(s1, s2)); //true
s2 = "akhil jain";
Console.WriteLine(object.ReferenceEquals(s1, s2)); //false
//Console.WriteLine(s1 == s2);
//Console.WriteLine(s1.Equals(s2));
string s3 = "akhil";
//1".Substring(0, 5);
Console.WriteLine(s3+" " +s1);
Console.WriteLine(object.ReferenceEquals(s1,s3)); //true
string s4 = "akhil1".Substring(0, 5);
Console.WriteLine(object.ReferenceEquals(s1, s4)); //confusion false why as s4 data is same as s1
答案 0 :(得分:2)
引用相同,因为字符串文字被 interned ,Substring
返回新的字符串和新的引用,它不会尝试秒猜出您的参数并检查实习生池
公共语言运行时通过维护一个 表,称为内部池,其中包含对 在其中以编程方式声明或创建的每个唯一文字字符串 您的程序。因此,带有 特定值在系统中仅存在一次。
例如,如果将相同的文字字符串分配给多个变量,则运行时将检索对文字的相同引用 实习生池中的字符串,并将其分配给每个变量。
但是,无用的事实3454345.2 ,从 .Net 2 开始,由于各种原因,您已经能够将其关闭
NoStringInterning 将程序集标记为不需要字符串字面量的实习。在应用领域中,常见的 语言运行时为每个唯一的字符串创建一个字符串对象 文字,而不是制作多个副本。这种行为称为 字符串实习,内部需要建立辅助表 消耗内存资源。
答案 1 :(得分:0)
实例化两个对象时,引用不相等。 Object.ReferenceEquals
方法因此返回false。但是,字符串是非常特殊的情况。如果在代码中声明字符串,则CLR将其保留在表中。这称为intern pool。这将导致使用相同值实例化的两个字符串引用内存中的同一对象。这将导致Object.ReferenceEquals
返回true。
通过代码中的某些操作形成字符串时,该字符串不会自动插入到池中。因此,尽管字符串的内容可能相同,但它具有不同的引用。 Object.ReferenceEquals
here的文档注释中也对此进行了解释。
请注意,String.Equals()
方法将返回true。在C#中,您还可以在字符串上使用'=='运算符。请在下面查看您调整后的代码。
string s1 = "akhil";
string s2 = "akhil";
Console.WriteLine(s1.Equals(s2)); //true
s2 = "akhil jain";
Console.WriteLine(s1.Equals(s2)); //false
string s3 = "akhil";
Console.WriteLine(s3 + " " + s1);
Console.WriteLine(s1.Equals(s3)); //true
string s4 = "akhil1".Substring(0, 5);
Console.WriteLine(s1.Equals(s4)); //this now returns true as well
Console.WriteLine(s1 == s4); //so does this
答案 2 :(得分:0)
object.ReferenceEquals的值为false,因为它检查两个引用是否都指向同一对象。 ReferenceEquals不会检查数据是否相等,但是两个对象是否占用相同的内存地址。
正如TheGeneral已经提到的那样,字符串文字会被插入并存储在称为“内部池”的表中。这是为了有效地存储字符串对象。
将字符串文字分配给多个变量时,它们指向内部池中的相同地址。因此,您对object.ReferenceEquals为真。但是,当您将其与子字符串进行比较时,会在内存中创建一个新对象。比较引用时会导致错误,因为它们是两个不同的对象,它们占用不同的内存位置。
所有动态创建的字符串或从外部源读取的字符串都不会自动插入。
如果尝试以下操作,则对object.ReferenceEquals为真。
Console.WriteLine(object.ReferenceEquals(s1, string.Intern(s4)));
您可以使用原始数据类型检查,即使将一个变量分配给另一个变量,ReferenceEquals也会返回false。
int a = 10;
int b = a;
Console.WriteLine(ReferenceEquals(a, b)); //false
这是因为每种基本类型都分别存储。