I have a condition in a silverlight application that compares 2 strings, for some reason when I use ==
it returns false while .Equals()
returns true.
Here is the code:
if (((ListBoxItem)lstBaseMenu.SelectedItem).Content.Equals("Energy Attack"))
{
// Execute code
}
if (((ListBoxItem)lstBaseMenu.SelectedItem).Content == "Energy Attack")
{
// Execute code
}
Any reason as to why this is happening?
When
==
is used on an expression of typeobject
, it'll resolve toSystem.Object.ReferenceEquals
.Equals
is just avirtual
method and behaves as such, so the overridden version will be used (which, forstring
type compares the contents).I am a bit confused here. If the runtime type of Content is of type string, then both == and Equals should return true. However, since this does not appear to be the case, then runtime type of Content is not string and calling Equals on it is doing a referential equality and this explains why Equals("Energy Attack") fails. However, in the second case, the decision as to which overloaded == static operator should be called is made at compile time and this decision appears to be ==(string,string). this suggests to me that Content provides an implicit conversion to string.
==
and.Equals
are both dependent upon the behavior defined in the actual type and the actual type at the call site. Both are just methods / operators which can be overridden on any type and given any behavior the author so desires. In my experience, I find it's common for people to implement.Equals
on an object but neglect to implement operator==
. This means that.Equals
will actually measure the equality of the values while==
will measure whether or not they are the same reference.When I'm working with a new type whose definition is in flux or writing generic algorithms, I find the best practice is the following
Object.ReferenceEquals
directly (not needed in the generic case)EqualityComparer<T>.Default
In some cases when I feel the usage of
==
is ambiguous I will explicitly useObject.Reference
equals in the code to remove the ambiguity.Eric Lippert recently did a blog post on the subject of why there are 2 methods of equality in the CLR. It's worth the read
Because the static version of the
.Equal
method was not mentioned so far, I would like to add this here to summarize and to compare the 3 variations.where
MyString
is a variable that comes from somewhere else in the code.Background info and to summerize:
In Java using
==
to compare strings should not be used. I mention this in case you need to use both languages and also to let you know that using==
can also be replaced with something better in C#.In C# there's no practical difference for comparing strings using Method 1 or Method 2 as long as both are of type string. However, if one is null, one is of another type (like an integer), or one represents an object that has a different reference, then, as the initial question shows, you may experience that comparing the content for equality may not return what you expect.
Suggested solution:
Because using
==
is not exactly the same as using.Equals
when comparing things, you can use the static String.Equals method instead. This way, if the two sides are not the same type you will still compare the content and if one is null, you will avoid the exception.It is a little more to write, but in my opinion, safer to use.
Here is some info copied from Microsoft:
Parameters
a
StringThe first string to compare, or
null
.b
StringThe second string to compare, or
null
.Returns
Boolean
true
if the value ofa
is the same as the value ofb
; otherwise,false
. If botha
andb
arenull
, the method returnstrue
.