Substring将创建另一个实例C#?

时间:2019-04-30 06:34:23

标签: c# string substring equals

我是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

3 个答案:

答案 0 :(得分:2)

引用相同,因为字符串文字 interned Substring返回新的字符串和新的引用,它不会尝试秒猜出您的参数并检查实习生池

String.Intern(String) Method

  

公共语言运行时通过维护一个   表,称为内部池,其中包含对   在其中以编程方式声明或创建的每个唯一文字字符串   您的程序。因此,带有   特定值在系统中仅存在一次。

     

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

但是,无用的事实3454345.2 ,从 .Net 2 开始,由于各种原因,您已经能够将其关闭

CompilationRelaxations Enum

  

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

这是因为每种基本类型都分别存储。