比较c#中的字符串和对象

时间:2021-12-04 16:21:44

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 by string (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 a NullReferenceException.

    如果任何一个参数都可以为空,那么使用静态Equals(object, object)方法是有用的;这意味着您不必担心NullReferenceException。

  • Make both variables of type string, at which point the == overload within string 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)

比较c#中的字符串和对象

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 by string (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 a NullReferenceException.

    如果任何一个参数都可以为空,那么使用静态Equals(object, object)方法是有用的;这意味着您不必担心NullReferenceException。

  • Make both variables of type string, at which point the == overload within string 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)

比较c#中的字符串和对象

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());