字符串不变性 C#(堆内存,新运算符)
String immutability C# (Heap memory, new operator)
最近学习了Stack和Heap,想请教一下。我一直在“试验”字符串,但我无法解释 - 如果我在堆上创建两个不同的内存块,为什么以下内容为真?
static void Main()
{
string test = "yes";
string secondTest = "yes";
Console.WriteLine(test == secondTest); //true
string thirdTest = new string("yes");
Console.WriteLine(secondTest == thirdTest); //true
}
第一个字符串test
和secondTest
是一样的,因为它们有相同的参考值,但是我创建第三个字符串thirdTest
的时候我不是在创建一个新的吗使用“new”在堆上分配内存块?
为什么还是这样?
我的猜测:
我写的完全一样,我误解了new
运算符,因为我看教程时,它们是Java语言
String name = "John"
String aThirdName = new String("John")
System.out.printIn(name == aThirdName); // false
这意味着我想的不一样
(string test = "yes") = (string thirdTest = new string("yes"))
其实是一样的。 (我的意思是这两行是类比的)
如果我的猜测是正确的,如何在堆上创建一个具有相同值的新内存块?
(我想知道,只是为了学习,我知道内存有很多相同值的变量在堆内部的不同内存块上是无效的)
如评论中所述,string
是一个不好的例子,因为它覆盖了 ==
运算符和覆盖了 equals
方法。对于字符串,它是一个引用类型,但由于许多覆盖和其他行为,它实际上(在大多数情况下)表现得像一个值类型(尤其是在相等性方面)。
也就是说,如果您要创建一个简单的 class,您会发现您的测试完全符合您的预期。
String 中覆盖相等性的片段,为您提供一些背景信息。
public static bool operator ==(string? a, string? b)
{
return string.Equals(a, b);
}
// Determines whether two Strings match.
public static bool Equals(string? a, string? b)
{
if (object.ReferenceEquals(a,b))
{
return true;
}
if (a is null || b is null || a.Length != b.Length)
{
return false;
}
return EqualsHelper(a, b);
}
然后它开始进入一个EqualsHelper
代码的兔子洞,这里不值得追逐(如果你有兴趣,你可以反编译它或在网上找到它)。
string firstTest=new string("test")
和 string secondTest="test"
是一样的,第二个版本只是语法糖。关于为什么firstTest==secondTest //true
,这就是为什么class 字符串覆盖方法Equals
和运算符(==)也被覆盖并使用Equals
。
最近学习了Stack和Heap,想请教一下。我一直在“试验”字符串,但我无法解释 - 如果我在堆上创建两个不同的内存块,为什么以下内容为真?
static void Main()
{
string test = "yes";
string secondTest = "yes";
Console.WriteLine(test == secondTest); //true
string thirdTest = new string("yes");
Console.WriteLine(secondTest == thirdTest); //true
}
第一个字符串test
和secondTest
是一样的,因为它们有相同的参考值,但是我创建第三个字符串thirdTest
的时候我不是在创建一个新的吗使用“new”在堆上分配内存块?
为什么还是这样?
我的猜测:
我写的完全一样,我误解了new
运算符,因为我看教程时,它们是Java语言
String name = "John"
String aThirdName = new String("John")
System.out.printIn(name == aThirdName); // false
这意味着我想的不一样
(string test = "yes") = (string thirdTest = new string("yes"))
其实是一样的。 (我的意思是这两行是类比的)
如果我的猜测是正确的,如何在堆上创建一个具有相同值的新内存块? (我想知道,只是为了学习,我知道内存有很多相同值的变量在堆内部的不同内存块上是无效的)
如评论中所述,string
是一个不好的例子,因为它覆盖了 ==
运算符和覆盖了 equals
方法。对于字符串,它是一个引用类型,但由于许多覆盖和其他行为,它实际上(在大多数情况下)表现得像一个值类型(尤其是在相等性方面)。
也就是说,如果您要创建一个简单的 class,您会发现您的测试完全符合您的预期。
String 中覆盖相等性的片段,为您提供一些背景信息。
public static bool operator ==(string? a, string? b)
{
return string.Equals(a, b);
}
// Determines whether two Strings match.
public static bool Equals(string? a, string? b)
{
if (object.ReferenceEquals(a,b))
{
return true;
}
if (a is null || b is null || a.Length != b.Length)
{
return false;
}
return EqualsHelper(a, b);
}
然后它开始进入一个EqualsHelper
代码的兔子洞,这里不值得追逐(如果你有兴趣,你可以反编译它或在网上找到它)。
string firstTest=new string("test")
和 string secondTest="test"
是一样的,第二个版本只是语法糖。关于为什么firstTest==secondTest //true
,这就是为什么class 字符串覆盖方法Equals
和运算符(==)也被覆盖并使用Equals
。