See this code:
看到这段代码:
object x = "mehdi emrani";
string y = "mehdi emrani";
Console.WriteLine(y == x);
that returns true
.
返回true。
But this code:
但这段代码:
object x = "mehdi emrani";
string y = "mehdi ";
y += "emrani";
Console.WriteLine(y == x);
returns false
.
返回false。
So when I compare String and Object in first code I get true
.
But when I compare them in second code I get false
.
当我在第一个代码中比较字符串和对象时,我得到了正确的结果。但是当我在第二段代码中比较它们时,我得到了false。
Both strings are same but why when I append to the string, my result returns false
?
两个字符串都是相同的,但是为什么当我附加到字符串时,结果返回false?
6 个解决方案
#1
89
In each case, the second operand of ==
is x
, which is of type object
. That means you're using the normal reference equality operator.
在每种情况下,==的第二个操作数是x,它是object类型。这意味着你使用的是标准引用等式运算符。
Now in your first case, you're using two string constants with the same contents. The C# compiler will use a single object for those two references. In the second case, x
and y
refer to distinct string objects with the same contents. The two references will be different, so ==
will return false.
在第一种情况下,使用两个字符串常量,内容相同。c#编译器将为这两个引用使用一个对象。在第二种情况下,x和y表示具有相同内容的不同字符串对象。这两个引用将不同,因此=将返回false。
You can fix the comparison by:
你可以通过以下方法修正比较:
-
Use
Equals
instead - that's overridden bystring
(as opposed to the==
operator which is only overloaded:使用Equals—它被string重写(与仅重载的==运算符相反):
Console.WriteLine(y.Equals(x)); // or x.Equals(y), or Equals(y, x)
The use of the static
Equals(object, object)
method can be useful if either of the arguments can be null; it means you don't need to worry about aNullReferenceException
.如果任何一个参数都可以为空,那么使用静态Equals(object, object)方法是有用的;这意味着您不必担心NullReferenceException。
-
Make both variables of type
string
, at which point the==
overload withinstring
will be picked at compile-time, and that overload compares the contents of the strings, not just the references使string类型的两个变量都具有相同的值,此时将在编译时选择string中的==重载,并且该重载将比较字符串的内容,而不仅仅是引用
It's worth noting that it's not just a matter of the string literals itself being noticed by the C# compiler - it's about compile-time constant expressions. So for example:
值得注意的是,这不仅仅是由c#编译器注意到的字符串文字本身的问题,而是关于编译时常量表达式的问题。举个例子:
object x = "mehdi emrani";
string y = "mehdi " + "emrani";
Console.WriteLine(y == x); // True
Here y
is initialized using two string literals which aren't the same as the one used to initialize x
, but the string concatenation is performed by the compiler, which realizes it's the same string it's already used for x
.
这里y是用两个字符串来初始化的,它们与用来初始化x的字符串不相同,但是字符串连接是由编译器执行的,编译器意识到它与x使用的字符串是相同的。
#2
30
When you initialized
当你初始化
object x = "mehdi emrani"; //pointer(x)
It initialized it in memory and assign reference to x. After this when you initialized
它在内存中初始化,并为x赋值,在初始化之后。
string y = "mehdi emrani"; //pointer(x)
compiler find that this value is already in memory so it assign same reference to y.
编译器发现这个值已经在内存中,所以它将相同的引用赋给y。
Now ==
equal operator which actually compares the addresses instead of value find the same address for both variable which results true:
现在== =等运算符,它实际比较的是地址而不是值为两个变量找到相同的地址,结果为真:
x==y //actually compares pointer(x)==pointer(x) which is true
In second case when you initialized x and y that get assigned different addresses.
在第二种情况下,初始化得到不同地址的x和y。
object x = "mehdi emrani"; //Pointer(x)
string y = "mehdi "; //not found in memory
y += "emrani"; //Pointer(y)
Now comparison find different addresses which results false:
现在比较发现不同的地址导致错误:
x == y //is actually Pointer(x) == Pointer(y) which is false
So to overcome this you need to use .Equals() which instead of reference compares the value and object type.
因此,要克服这个问题,需要使用. equals(),它代替reference来比较值和对象类型。
Console.WriteLine(y.Equals(x)); //compares "mehdi emrani" == "mehdi emrani" results true
#3
8
Most probably the references are compared (standard Equals
implementation for object). In the first example C# optimizes constant strings, and so y and x actually point to the same object, hence their reference is equal. In the other case, y is created dynamically, and so the reference is different.
最可能的是对引用进行比较(对象的标准等于实现)。在第一个例子中,c#优化了常量字符串,因此y和x实际上指向同一个对象,因此它们的引用是相等的。在另一种情况下,y是动态创建的,因此引用是不同的。
#4
7
In the background a new string is created every time you modify an existing one, because strings are immutable, which means they can't change.
在后台,每次修改现有字符串时都会创建一个新的字符串,因为字符串是不可变的,这意味着它们不能更改。
See the following for an explanation: Why .NET String is immutable?
请看下面的解释:为什么。net字符串是不可变的?
#5
7
In the first case, .NET performs string constant optimization and allocates only one String instance. Both x and y points to same object (both the references are equal).
在第一个例子中,. net执行字符串常量优化,并且只分配一个字符串实例。x和y都指向同一个对象(两个引用都相等)。
But in the second case x and y are pointing to different String instances. Adding "ermani" to y creates a third string object.
但是在第二种情况下x和y指向不同的字符串实例。向y添加“ermani”将创建第三个字符串对象。
"==" operator basically returns true if operands on both sides refer to same object. In the first case x and y refer to same object and in the seconds case x & y refer different objects.
如果两边的操作数都引用相同的对象,则运算符基本上返回true。在第一种情况下,x和y指的是相同的对象,在第二种情况下,x和y指的是不同的对象。
#6
4
Have you tried:
你有试过:
Console.WriteLine(y == x.ToString());
#1
89
In each case, the second operand of ==
is x
, which is of type object
. That means you're using the normal reference equality operator.
在每种情况下,==的第二个操作数是x,它是object类型。这意味着你使用的是标准引用等式运算符。
Now in your first case, you're using two string constants with the same contents. The C# compiler will use a single object for those two references. In the second case, x
and y
refer to distinct string objects with the same contents. The two references will be different, so ==
will return false.
在第一种情况下,使用两个字符串常量,内容相同。c#编译器将为这两个引用使用一个对象。在第二种情况下,x和y表示具有相同内容的不同字符串对象。这两个引用将不同,因此=将返回false。
You can fix the comparison by:
你可以通过以下方法修正比较:
-
Use
Equals
instead - that's overridden bystring
(as opposed to the==
operator which is only overloaded:使用Equals—它被string重写(与仅重载的==运算符相反):
Console.WriteLine(y.Equals(x)); // or x.Equals(y), or Equals(y, x)
The use of the static
Equals(object, object)
method can be useful if either of the arguments can be null; it means you don't need to worry about aNullReferenceException
.如果任何一个参数都可以为空,那么使用静态Equals(object, object)方法是有用的;这意味着您不必担心NullReferenceException。
-
Make both variables of type
string
, at which point the==
overload withinstring
will be picked at compile-time, and that overload compares the contents of the strings, not just the references使string类型的两个变量都具有相同的值,此时将在编译时选择string中的==重载,并且该重载将比较字符串的内容,而不仅仅是引用
It's worth noting that it's not just a matter of the string literals itself being noticed by the C# compiler - it's about compile-time constant expressions. So for example:
值得注意的是,这不仅仅是由c#编译器注意到的字符串文字本身的问题,而是关于编译时常量表达式的问题。举个例子:
object x = "mehdi emrani";
string y = "mehdi " + "emrani";
Console.WriteLine(y == x); // True
Here y
is initialized using two string literals which aren't the same as the one used to initialize x
, but the string concatenation is performed by the compiler, which realizes it's the same string it's already used for x
.
这里y是用两个字符串来初始化的,它们与用来初始化x的字符串不相同,但是字符串连接是由编译器执行的,编译器意识到它与x使用的字符串是相同的。
#2
30
When you initialized
当你初始化
object x = "mehdi emrani"; //pointer(x)
It initialized it in memory and assign reference to x. After this when you initialized
它在内存中初始化,并为x赋值,在初始化之后。
string y = "mehdi emrani"; //pointer(x)
compiler find that this value is already in memory so it assign same reference to y.
编译器发现这个值已经在内存中,所以它将相同的引用赋给y。
Now ==
equal operator which actually compares the addresses instead of value find the same address for both variable which results true:
现在== =等运算符,它实际比较的是地址而不是值为两个变量找到相同的地址,结果为真:
x==y //actually compares pointer(x)==pointer(x) which is true
In second case when you initialized x and y that get assigned different addresses.
在第二种情况下,初始化得到不同地址的x和y。
object x = "mehdi emrani"; //Pointer(x)
string y = "mehdi "; //not found in memory
y += "emrani"; //Pointer(y)
Now comparison find different addresses which results false:
现在比较发现不同的地址导致错误:
x == y //is actually Pointer(x) == Pointer(y) which is false
So to overcome this you need to use .Equals() which instead of reference compares the value and object type.
因此,要克服这个问题,需要使用. equals(),它代替reference来比较值和对象类型。
Console.WriteLine(y.Equals(x)); //compares "mehdi emrani" == "mehdi emrani" results true
#3
8
Most probably the references are compared (standard Equals
implementation for object). In the first example C# optimizes constant strings, and so y and x actually point to the same object, hence their reference is equal. In the other case, y is created dynamically, and so the reference is different.
最可能的是对引用进行比较(对象的标准等于实现)。在第一个例子中,c#优化了常量字符串,因此y和x实际上指向同一个对象,因此它们的引用是相等的。在另一种情况下,y是动态创建的,因此引用是不同的。
#4
7
In the background a new string is created every time you modify an existing one, because strings are immutable, which means they can't change.
在后台,每次修改现有字符串时都会创建一个新的字符串,因为字符串是不可变的,这意味着它们不能更改。
See the following for an explanation: Why .NET String is immutable?
请看下面的解释:为什么。net字符串是不可变的?
#5
7
In the first case, .NET performs string constant optimization and allocates only one String instance. Both x and y points to same object (both the references are equal).
在第一个例子中,. net执行字符串常量优化,并且只分配一个字符串实例。x和y都指向同一个对象(两个引用都相等)。
But in the second case x and y are pointing to different String instances. Adding "ermani" to y creates a third string object.
但是在第二种情况下x和y指向不同的字符串实例。向y添加“ermani”将创建第三个字符串对象。
"==" operator basically returns true if operands on both sides refer to same object. In the first case x and y refer to same object and in the seconds case x & y refer different objects.
如果两边的操作数都引用相同的对象,则运算符基本上返回true。在第一种情况下,x和y指的是相同的对象,在第二种情况下,x和y指的是不同的对象。
#6
4
Have you tried:
你有试过:
Console.WriteLine(y == x.ToString());