In this lesson, you will learn how to define your own rules for determining when two objects are considered "equal" so that collections like Dictionary or HashSet can organize them exactly how you want.
Why Customize Equality?
By default, C# collections check if two reference-type objects are the exact same instance in memory. However, sometimes you want "equality" to mean something else. For example, if you have a Product class with an Id, you might want two different objects to be treated as the same product if their Id properties match, even if they are stored in different places in memory.
Implementing IEqualityComparer<T>
To achieve this, we implement the IEqualityComparer<T> interface. This requires two main methods:
Equals(T x, T y): Defines the logic for comparing two objects.GetHashCode(T obj): Generates a numeric "bucket" ID for the object.
If two objects are "equal" according to your logic, they must return the same hash code. If they don’t, your HashSet or Dictionary will fail to find them!
Practical Example
Imagine we want to treat products as identical if they share the same Sku string:
public class ProductSkuComparer : IEqualityComparer<Product>
{
public bool Equals(Product x, Product y)
{
if (x == null || y == null) return false;
return x.Sku == y.Sku;
}
public int GetHashCode(Product obj)
{
return obj.Sku?.GetHashCode() ?? 0;
}
}
Once defined, you can pass this custom comparer into the constructor of a collection:
var uniqueProducts = new HashSet<Product>(new ProductSkuComparer());
When you add items to this HashSet, it now uses your ProductSkuComparer instead of the default reference check. It calculates the hash code using the Sku and, if a collision occurs, uses your Equals method to verify if they are truly the same. This allows you to enforce business-specific rules on collection membership while keeping your data classes clean.
Key Takeaway: Custom equality allows you to override default memory-address comparison by implementing IEqualityComparer<T> to provide your own logical rules and consistent hashing.