Equals() vs == in C#

Equals() vs == in C#

In C#, both the equals() method and the == operator are used for **comparison**, but they behave differently based on whether the comparison is performed on **value types or reference types**.

Understanding the == Operator

The == operator compares **values** for primitive types (like int, char), but for reference types (like object, class), it checks **reference equality**.

Example 1: == with Primitive Types

int a = 10;
int b = 10;

Console.WriteLine(a == b);  // Output: True (compares values)
        

Example 2: == with Reference Types

string str1 = "Hello";
string str2 = "Hello";
string str3 = new string("Hello".ToCharArray());

Console.WriteLine(str1 == str2);  // Output: True (string interning applies)
Console.WriteLine(str1 == str3);  // Output: True (string content comparison)
Console.WriteLine((object)str1 == (object)str3);  // Output: False (different references)
        

In this example:

  • For **string literals**, == compares values (interning applies).
  • For **string objects**, == still compares content.
  • When casting to **object**, == checks reference equality, which may differ.

Understanding the equals() Method

The equals() method compares **object content** rather than references. It is **overridable** and can be customized in user-defined classes.

Example: Using Equals() Method

string a = "Hello";
string b = "Hello";
string c = new string("Hello".ToCharArray());

Console.WriteLine(a.Equals(b));  // Output: True (content comparison)
Console.WriteLine(a.Equals(c));  // Output: True (content comparison)
        

Example: Overriding Equals() in Custom Class

class Person
{
    public string Name { get; set; }

    public override bool Equals(object obj)
    {
        if (obj is Person other)
        {
            return this.Name == other.Name;
        }
        return false;
    }
}

Person p1 = new Person { Name = "Alice" };
Person p2 = new Person { Name = "Alice" };

Console.WriteLine(p1 == p2);        // Output: False (reference comparison)
Console.WriteLine(p1.Equals(p2));   // Output: True (customized content comparison)
        

In this example:

  • == compares references (which are different).
  • equals() compares **object content**.
  • By overriding equals(), we allow content-based comparison.

Equals() vs ==: Key Differences

The following table highlights the **key differences** between equals() and ==:

Aspect equals() Method == Operator
Purpose Compares **object content**. For value types, compares values. For reference types, compares **object references**.
Overridable Yes, can be overridden in custom classes. No, except for certain types like string.
Comparison Type Compares **values/content**. Compares **references (for objects) or values (for primitives)**.

Best Practices

  • Use == for primitive types like int, bool, char, etc.
  • Use equals() for reference types when comparing **object content**.
  • Always **override equals()** in custom classes when content-based comparison is required.
  • For collections like **Dictionary, HashSet**, ensure Equals() and GetHashCode() are properly implemented.