Confusing use of the == operator in C #

I am embarrassed at using == in (C #) when I use a literal string, like here:

 object a="hello"; object b="hello"; 

the comparison a==b will be performed.

but when i use an object like here:

 object c=new StringBuilder("hello").ToString(); object d=new StringBuilder("hello").ToString(); 

comparing a==b will be false.

although a,b,c,d all System.Object types at compile time and == operator comparison values ​​depend on their values ​​at compile time.

I use the extension method to get the varabiles type at compile time:

 public static class MiscExtensions { public static Type GetCompileTimeType<T>(this T dummy) { return typeof(T); } } 
+5
source share
6 answers
 object a="hello"; object b="hello"; 

Here, the compiler creates an instance of a single string for the literal "hello" . Therefore, a and b indicate the same instance.

In the second fragment c and d specify different string instances.

However, it is important that a == b and c == d do not call the == operator of the string class, but object . Thus, a simple link comparison is performed, not a string comparison.

+17
source

Note that you are comparing object , not string !

It's right:

 string c = new StringBuilder("hello").ToString(); string d = new StringBuilder("hello").ToString(); c == d; // true 

or that:

 var c = new StringBuilder("hello").ToString(); var d = new StringBuilder("hello").ToString(); c == d; // true 

(because in this case var will implicitly enter variables as a result of StringBuilder.ToString() , which is equal to string ), see here for more information


Do not mix object and string comparisons.

In your base case, the comparison led to true, because it was actually the same object!

In the second case, you have two "new" operators, therefore, two different string builders that generate two new string objects. Not the same persistent string object.

The comparison used is determined by the type of your variables.

+7
source

For reference types other than a string, == returns true if its two operands refer to the same object.

In the first example:

 object a="hello"; object b="hello"; 

a and b point to the same object, therefore they are equal, and in the second:

 object c=new StringBuilder("hello").ToString(); object d=new StringBuilder("hello").ToString(); 

you create two different instances of StringBuilder: c and d , so they point to different objects and NOT is (false)

You can find more information on Microsoft Docs .

+2
source

On the msdn page:

For predefined value types, the equality operator (==) returns true if the values ​​of its operands are equal, otherwise false. For reference, types other than string, == returns true if its two operands reference the same object. For string type == compares string values.

Thus, both comparisons should not be equal, since you specifically use the object instead of the string.

However, the C # compiler is optimized and recognizes that you are using two identical string literals, so the compiler combines two strings into one object, so comparing objects is true. but the compiler cannot merge StringBuilder instances, because you are creating new objects using the new keyword.

+2
source

When you use the constant "hello", the compiler will generate an interned version of this line and use this value for a and b.

When using StringBuilder and ToString, two separate instances of the string containing "hello" will be compared.

If you want to check for equality of strings, you should use the Equals () method

+1
source
 object a="hello"; object b="hello"; 

Here, both a and b point to the same object. To be specific, they point to the same memory. If in the second example

 object c=new StringBuilder("hello").ToString(); object d=new StringBuilder("hello").ToString(); 

Here you create a new instance to be specific, the memory location changes for both c and d. so this is the reason a == b and c! = d.

+1
source

Source: https://habr.com/ru/post/1271322/


All Articles