This page contains general knowledge about the usage of Equals, IComparar and IComparable in C# Equals in C# can be used to compare advanced objects rather than just the value of an int or a string.
// True comparison with integers
int a = 5;
int b = 5;
bool result = a.Equals(b); // true - same value
// False comparison with integers
int c = 5;
int d = 10;
bool result2 = c.Equals(d); // false - different values
// True comparison with strings
string str1 = "hello";
string str2 = "hello";
bool result = str1.Equals(str2); // true - same content
// False comparison with strings
string str3 = "hello";
string str4 = "world";
bool result2 = str3.Equals(str4); // false - different content
// Case-sensitive comparison (false)
string str5 = "Hello";
string str6 = "hello";
bool result3 = str5.Equals(str6); // false - different case
// Case-insensitive comparison (true)
bool result4 = str5.Equals(str6, StringComparison.OrdinalIgnoreCase); // true
// Default behavior for reference types (comparing references, not content)
class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
// False comparison - different references even with same content
Person person1 = new Person { Name = "John", Age = 30 };
Person person2 = new Person { Name = "John", Age = 30 };
bool result = person1.Equals(person2); // false - different objects in memory
// True comparison - same reference
Person person3 = person1;
bool result2 = person1.Equals(person3); // true - same object in memory
class Employee
{
public string Name { get; set; }
public int EmployeeId { get; set; }
public override bool Equals(object obj)
{
// Check if null or different type
if (obj == null || GetType() != obj.GetType())
return false;
// Cast to Employee
Employee other = (Employee)obj;
// Compare by EmployeeId
return EmployeeId == other.EmployeeId;
}
// Always override GetHashCode when overriding Equals
public override int GetHashCode()
{
return EmployeeId.GetHashCode();
}
}
// Usage examples
Employee emp1 = new Employee { Name = "Alice", EmployeeId = 101 };
Employee emp2 = new Employee { Name = "Bob", EmployeeId = 101 };
Employee emp3 = new Employee { Name = "Charlie", EmployeeId = 102 };
bool result1 = emp1.Equals(emp2); // true - same EmployeeId despite different Names
bool result2 = emp1.Equals(emp3); // false - different EmployeeId
Here's a comparison between the Equals method and standard comparison operators in C#:
| Feature | Equals Method | Standard Operators (==, !=, etc.) |
|---|---|---|
| Reference types | Default compares references, can be overridden to compare values | Compares references by default |
| Value types | Compares values | Compares values |
| Null handling | Safer: obj.Equals(null) returns false without exceptions | Can cause NullReferenceException if left operand is null |
| Polymorphism | Can be overridden for customized comparison logic | Operators can be overloaded but with limitations |
| String comparison | Offers options like StringComparison.OrdinalIgnoreCase | Basic comparison only, needs extra code for case insensitivity |
Wanting to sort a list of numbers and or text is fairly easy in C# as this can be done automatically. Sorting a list of objects however is a different story as C# does not know by default which object property you wish to sort to accordingly. This is where IComparable<T> and and IComparar<T> comes in.
Using IComparable<T> means you allow your class to compare itself to other objects of the same type. This is done using the method called CompareTo. This method is what tells explains what is to be compared.