C# FAQ: When should Equals and == be used

Microsoft .NET Framework, ASP.NET, Visual C# (CSharp, C Sharp, C-Sharp) Developer Training, Visual Studio


Jump to: navigation, search
CSharp-Online.NET:FAQs
edit

When should Equals and == be used?

The == operator is an operator which can be overloaded; but, it has a default identity behavior. The Equals method is a virtual method defined in System.Object. It, also, has a default identity behavior, and Equals can be overridden by a local implementation.

With reference types and when the == operator has not been overloaded, == compares two references to determine whether they refer to the same object: this behavior is identical to the default implementation of Equals in System.Object.

While value types do not provide a default overload behavior for ==, most value types provided by the .NET framework do include their own overload. For example, the default implementation of Equals for a value type is provided by ValueType; and, it uses reflection to make the comparison. The use of reflection makes the default implementation significantly slower than a type-specific implementation might be. Also, this implementation invokes Equals on pairs of references within the two values being compared.

The primary difference between the two types of comparison in normal use—when custom value types are not in use—is polymorphism. Operators are overloaded rather than overridden. Therefore, the compiler will simply call the identity version; unless, it knows to call the more specific version. By way of illustration, examine the following example:

using System;
 
public class Test
{
   static void Main()
   {
      // Create two equal but distinct strings
      string str1 = new string (new char[] {'C', 'S', 'O'});
      string str2 = new string (new char[] {'C', 'S', 'O'});
        
      Console.WriteLine (str1 == str2);
      Console.WriteLine (str1.Equals(str2));
        
      // Try the same tests with variables of type object
      object object1 = str1;
      object object2 = str2;
        
      Console.WriteLine (object1 == object2);
      Console.WriteLine (object1.Equals(object2));
   }
}

The results are:


 Illustration of default behavior (program output)
True

True False True


The third output value is False; because, the compiler does not know that the contents of object1 and object2 are both string references. Therefore, it can only call the non-overloaded version of ==. The identity operator returns false; because, the references are to different strings.

A rule of thumb is that for most reference types, use Equals when the test is for equality rather than for reference identity. However, strings may be an exception: string comparison with == seems simpler and more readable. But, remember that both sides of the operator must be expressions of type string in order for the comparison to work correctly.

For value types, use == for code which is easy to read. If a value type provides an overload for == which behaves differently to Equals, problems may result.



Personal tools