5

I am confusing about using == in (c#) when I use literal string like here:

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

the comparison a==b will be true.

but when I use object like here:

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

the comparison a==b will be false.

even though a,b,c,d all of type System.Object in compile time and == operator compare values depends on their values in compile time.

I use extension method to get type of varabiles during compile time:

public static class MiscExtensions
{
    public static Type GetCompileTimeType<T>(this T dummy)
    { return typeof(T); }
}
6
  • 3
    Interned string object compared with == as reference equality will return false (see stackoverflow.com/questions/1766492/…). Commented Aug 29, 2017 at 9:27
  • I think you are more confused about different types in C#. Object, string and StringBuilder are not the same, that's why they have different names. ;) Commented Aug 29, 2017 at 9:29
  • similar questions here : stackoverflow.com/questions/27710665/… Commented Aug 29, 2017 at 9:37
  • 1
    Why are you using GetCompileTimeType for exactly? I don't see how it's relevant to your question Commented Aug 29, 2017 at 10:49
  • Since == operator determined based on the compile-time I was confused because this method determine that all variables are object type at compile-time. after answers I have recognized that no matter if they are all objects, but what is important here if these objects (a&b) or (c&d) point to same memory allocation or not. Commented Aug 29, 2017 at 11:33

6 Answers 6

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

Here the compiler creates a single string instance for the literal "hello". So a and b point to the same instance.

In your second snippet c and d point to different string instances.

The important point however is that a == b and c == d don't call the == operator of the string class, but of object. So a simple reference comparison is executed, not a string comparison.

Sign up to request clarification or add additional context in comments.

1 Comment

@mark have a look to the official documentation. They say that equality is done by reference instead for string. René Vogt is correct with this answer
7

Note here that you are comparing objectand not string !

This would have given true :

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

c == d; // true

or this :

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

c == d; // true

(because in this case, var will implicitly type the variables as the result of the expression, StringBuilder.ToString(), which is string), see here for more information


Don't mix object comparison and string comparison.

On your basic case, comparison led to true because it was actually the same object !

On the second case, you have two "new" statements, hence two different string builder, which generates two new string objects. Not the same constant string object.

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

2 Comments

Adding to this answer, here's a link that explains the var-keyword in more detail
yes, I will add a word on this in my answer, thank you
2

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

In first example:

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

a and b point to the same object, so they are equal, but in 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 are NOT equal (false)

More details you can find on Microsoft Docs.

Comments

2

From the msdn page:

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

So both comparisons should not be equal, since you are specifically casting to an object instead of a string.

However the c# compiler is optimized and recognizes that you are using two identical string literals, thus the compiler merges the two strings into one object, hence the object comparison is true. but the compiler cannot merge the StringBuilder instances since you are constructing new objects using the new keyword.

Comments

1

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

When you use a StringBuilder and ToString two separate instances of a string containing "hello" will be compared.

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

Comments

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

Here both a and b are pointing to same object. To be specific they are pointing to same memory. Whereas in second example

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

Here you are creating a new instance, to be specific the memory location varies for both c and d. so that is the reason a==b and c!=d.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.