Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why comparing two strings as object causes unexpected result

Consider the following piece of code.

object str = new string(new char[] { 't', 'e', 's', 't' });
object str1 = new string(new char[] { 't', 'e', 's', 't' });
Console.WriteLine(str==str1); // false
Console.WriteLine(str.Equals(str1));  // true

I understand the equality operator working here that as we have implicitly casted to object, the equality operator is checking the references of both if they are equal and returns false.

But i am confused on the second one, returning true looks like it is calling Equals override implementation provided by the String type and it checks for content of string if they are equal.

My question is why it doesn't check for content equality for operator as well, their actual type is string not object. right ?

while the follwing code outputs ture for both:

object str = "test";
object str1 = "test";
Console.WriteLine(str==str1); // true
Console.WriteLine(str.Equals(str1)); // true
like image 368
Ehsan Sajjad Avatar asked Jul 13 '16 11:07

Ehsan Sajjad


People also ask

What happens when you compare two string objects with the operator?

In String, the == operator is used to comparing the reference of the given strings, depending on if they are referring to the same objects. When you compare two strings using == operator, it will return true if the string variables are pointing toward the same java object. Otherwise, it will return false .

Why can't we use == to compare string objects?

You should not use == (equality operator) to compare these strings because they compare the reference of the string, i.e. whether they are the same object or not. On the other hand, equals() method compares whether the value of the strings is equal, and not the object itself.

What is the complexity of comparing two strings?

String comparisons typically do a linear scan of the characters, returning false at the first index where characters do not match. The time complexity is O(N) and the actual time taken depends on how many characters need to be scanned before differences statistically emerge.

What happens when you compare strings in Java?

Using String. equals() :In Java, string equals() method compares the two given strings based on the data/content of the string. If all the contents of both the strings are same then it returns true. If any character does not match, then it returns false.


1 Answers

With:

Console.WriteLine(str==str1); // false

it is determined at compile-time which C# pre-defined (formal) overload of operator == to use. Since str and str1 are declared as object, the overload operator ==(object, object) is chosen. This is fixed at compile-time. Just because the actual run-time types happen to be more specific, that does not change. If you want binding at run-time, use Console.WriteLine((dynamic)str == (dynamic)str1); /* true */ instead.

With:

Console.WriteLine(str.Equals(str1));  // true

you call a virtual method on object. Virtual means it will go to whatever override is relevant at run-time. The class System.String has an override, and since str will have run-time type System.String, the override will be used by the "virtual dispatch".


Regarding the addition to the bottom of your question: That situation is different because of string interning. String interning is an optimization where the same physical instance is used for formally distinct strings whose values are identical. When you have two strings whose values are given in the source code, string interning will "optimize" and make two references to the same instance. This is usually harmless because strings are guaranteed to be immutable. So normally you do not care if it is the same instance or another instance with identical value. But in your example, we can "reveal" the interning.

Note: String interning was not relevant to your original question. Only after you added a new example to your question, string interning became relevant.

like image 165
Jeppe Stig Nielsen Avatar answered Oct 12 '22 03:10

Jeppe Stig Nielsen