What is the difference between .Equals and == [duplicate]
Asked Answered
A

9

41

What is the difference between a.Equals(b) and a == b for value types, reference types, and strings? It would seem as though a == b works just fine for strings, but I'm trying to be sure to use good coding practices.

Actual answered 21/4, 2009 at 14:50 Comment(1)
Have a look at https://mcmap.net/q/20530/-or-equalsMardellmarden
R
38

From When should I use Equals and when should I use ==:

The Equals method is just a virtual one defined in System.Object, and overridden by whichever classes choose to do so. The == operator is an operator which can be overloaded by classes, but which usually has identity behaviour.

For reference types where == has not been overloaded, it compares whether two references refer to the same object - which is exactly what the implementation of Equals does in System.Object.

Value types do not provide an overload for == by default. However, most of the value types provided by the framework provide their own overload. The default implementation of Equals for a value type is provided by ValueType, and uses reflection to make the comparison, which makes it significantly slower than a type-specific implementation normally would be. This implementation also calls Equals on pairs of references within the two values being compared.

using System;

public class Test
{
    static void Main()
    {
        // Create two equal but distinct strings
        string a = new string(new char[] {'h', 'e', 'l', 'l', 'o'});
        string b = new string(new char[] {'h', 'e', 'l', 'l', 'o'});

        Console.WriteLine (a==b);
        Console.WriteLine (a.Equals(b));

        // Now let's see what happens with the same tests but
        // with variables of type object
        object c = a;
        object d = b;

        Console.WriteLine (c==d);
        Console.WriteLine (c.Equals(d));
    }
}

The result of this short sample program is

True
True
False
True
Rissa answered 21/4, 2009 at 14:54 Comment(1)
I could be wrong but I think line with Console.WriteLine (c.Equals(d)); here is misleading, because for reference types Equals will compare values of references, what is important. And here it is True only because in runtime variable "b" contains string instance, and String overrides virtual Equals(object d) method, and its logic contain comparison of strings exact values char by char. In this scenario it will be really same strings values of "hello", but in case of different strings in will lead to False in result of Equals method.Adigranth
D
12

Here is a great blog post about WHY the implementations are different.

Essentially == is going to be bound at compile time using the types of the variables and .Equals is going to be dynamically bound at runtime.

Diathermic answered 21/4, 2009 at 15:0 Comment(1)
+1 for the Lippert link, I was looking for this earlier!Gonta
A
11

In the most shorthand answer:

== opertator is to check identity. (i.e: a==b are these two are the same object?)

.Equals() is to check value. (i.e: a.Equals(b) are both holding identical values?)

With one exception:
For string and predefined value types (such as int, float etc..),
the operator == will answer for value and not identity. (same as using .Equals())

Amoroso answered 18/6, 2012 at 13:36 Comment(0)
V
8

One significant difference between them is that == is a static binary operator that works on two instances of a type whereas Equals is an instance method. The reason this matters is that you can do this:

Foo foo = new Foo()
Foo foo2 = null;
foo2 == foo;

But you cannot do this without throwing a NullReferenceException:

Foo foo = new Foo()
Foo foo2 = null;
foo2.Equals(foo);
Versify answered 21/4, 2009 at 14:55 Comment(1)
I found out Object.Equals(x,y) wont give NullReferenceExceptionPoulos
S
7

At a simple level, the difference is which method is called. The == method will attempt ot bind to operator== if defined for the types in question. If no == is found for value types it will do a value comparison and for reference types it will do a reference comparison. A .Equals call will do a virtual dispatch on the .Equals method.

As to what the particular methods do, it's all in the code. Users can define / override these methods and do anything they please. Ideally this methods should be equivalent (sorry for the pun) and have the same output but it is not always the case.

Slack answered 21/4, 2009 at 14:54 Comment(1)
+1 Good to mention that Equals is a virtual method.Versify
U
4

One simple way to help remember the difference is that a.Equals(b) is more analogous to
a == (object)b.

The .Equals() method is not generic and accepts an argument of type "object", and so when comparing to the == operator you have to think about it as if the right-hand operand were cast to object first.

One implication is that a.Equals(b) will nearly always return some value for a and b, regardless of type (the normal way to overload is to just return false if b is an unkown type). a == b will just throw an exception if there's no comparison available for those types.

Unruly answered 21/4, 2009 at 15:5 Comment(0)
P
0

"==" is an operator that can be overloaded to perform different things based on the types being compared.

The default operation performed by "==" is a.Equals(b);

Here's how you could overload this operator for string types:

public static bool operator == (string str1, string str2) 
{
    return (str1.Length == str2.Length;)
}

Note that this is different than str1.Equals(str2);

Derived classes can also override and redefine Equals().

As far as "best practices" go, it depends on your intent.

Pasty answered 21/4, 2009 at 14:52 Comment(2)
Could you clarify what yo mean by "The default operation performed by "==" is a.Equals(b)".Gonta
If you don't overload the '==' operator, it does the same thing as the Equals() function does. For strings, it does a string comparison, for user types it compares references.Pasty
M
0

By default, both == and .Equals() are equivalent apart from the possibility of calling .Equals() on a null instance (which would give you a NullReferenceException). You can, however, override the functionality of either of them independently (though I'm not sure that would ever be a good idea unless you're trying to work around the shortcomings of another system), which would mean you could MAKE them different.

You'll find people on both sides of the aisle as to the one to use. I prefer the operator rather than the function.

If you're talking about strings, though, it's likely a better idea to use string.Compare() instead of either one of those options.

Manny answered 21/4, 2009 at 14:56 Comment(0)
G
0

For strings you want to be careful of culture specific comparisons. The classic example is the german double S, that looks a bit like a b. This should match with "ss" but doesn't in a simple == comparison.

For string comparisons that are culture sensitive use: String.Compare(expected, value, StringComparison....) == 0 ? with the StringComparison overload you need.

Galateah answered 21/4, 2009 at 14:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.