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