看到这段代码:
object x = "mehdi emrani";
string y = "mehdi emrani";
Console.WriteLine(y == x);
Run Code Online (Sandbox Code Playgroud)
返回true.
但是这段代码:
object x = "mehdi emrani";
string y = "mehdi ";
y += "emrani";
Console.WriteLine(y == x);
Run Code Online (Sandbox Code Playgroud)
回报false.
因此,当我在第一个代码中比较String和Object时,我得到了true.
但是当我在第二个代码中比较它时,我得到了false.
两个字符串都相同,但为什么当我追加到字符串时,我的结果会返回false?
Jon*_*eet 91
在每种情况下,第二个操作数==是x,是类型的object.这意味着您正在使用普通的引用相等运算符.
现在,在第一种情况下,您使用两个具有相同内容的字符串常量.C#编译器将为这两个引用使用单个对象.在第二种情况下,x与y参照不同的字符串对象具有相同的内容.两个引用将是不同的,因此==将返回false.
您可以通过以下方式修复比较:
使用Equals代替-这是重写的string(而不是在==这是只有运营商超载:
Console.WriteLine(y.Equals(x)); // or x.Equals(y), or Equals(y, x)
Run Code Online (Sandbox Code Playgroud)
Equals(object, object)如果任一参数可以为null,则使用静态方法会很有用; 这意味着你不必担心NullReferenceException.
创建两个类型的变量string,此时将在编译时选择==内部重载string,并且该重载比较字符串的内容,而不仅仅是引用
值得注意的是,这不仅仅是C#编译器注意到字符串文字本身的问题 - 它是关于编译时常量表达式的.例如:
object x = "mehdi emrani";
string y = "mehdi " + "emrani";
Console.WriteLine(y == x); // True
Run Code Online (Sandbox Code Playgroud)
这里y使用两个字符串文字,其初始化是不一样用来初始化一个x,但字符串连接是由编译器,实现了它,它已经用于相同的字符串进行x.
Zah*_*med 30
初始化时
object x = "mehdi emrani"; //pointer(x)
Run Code Online (Sandbox Code Playgroud)
它在内存中初始化它并分配对x的引用.在此之后,您初始化
string y = "mehdi emrani"; //pointer(x)
Run Code Online (Sandbox Code Playgroud)
编译器发现该值已经在内存中,因此它为y分配了相同的引用.
现在==,实际比较地址而不是值的相等运算符为两个变量找到相同的地址,结果为true:
x==y //actually compares pointer(x)==pointer(x) which is true
Run Code Online (Sandbox Code Playgroud)
在第二种情况下,当您初始化x和y时,会分配不同的地址.
object x = "mehdi emrani"; //Pointer(x)
string y = "mehdi "; //not found in memory
y += "emrani"; //Pointer(y)
Run Code Online (Sandbox Code Playgroud)
现在比较找到导致错误的不同地址:
x == y //is actually Pointer(x) == Pointer(y) which is false
Run Code Online (Sandbox Code Playgroud)
因此,要克服这一点,您需要使用.Equals()而不是引用来比较值和对象类型.
Console.WriteLine(y.Equals(x)); //compares "mehdi emrani" == "mehdi emrani" results true
Run Code Online (Sandbox Code Playgroud)
最有可能的是引用被比较(Equals对象的标准实现).在第一个例子中,C#优化常量字符串,因此y和x实际上指向同一个对象,因此它们的引用是相等的.在另一种情况下,y是动态创建的,因此引用是不同的.
在后台,每次修改现有字符串时都会创建一个新字符串,因为字符串是不可变的,这意味着它们无法更改.
请参阅以下内容以获得解释:为什么.NET String是不可变的?
在第一种情况下,.NET执行字符串常量优化并仅分配一个String实例.x和y都指向同一个对象(两个引用都相等).
但在第二种情况下,x和y指向不同的String实例.将"ermani"添加到y会创建第三个字符串对象.
如果双方的操作数都引用同一个对象,则"=="运算符基本上返回true.在第一种情况下,x和y引用相同的对象,在秒的情况下,x和y引用不同的对象.
你有没有尝试过:
Console.WriteLine(y == x.ToString());
Run Code Online (Sandbox Code Playgroud)