-1

I'm currently working on a .net 5.0 application.

I need to implement an IEqualityComparer.

What is the correct way, to implement this interface and prevent NullRefrence Exceptions?

  • My class to compare looks like this:
public class Fruit 
{
   public int Id { get; set; }

   public string Name { get; set; }
}
  • My IEqualityComparer should compare the Ids and looks like this
public class FruitComparer : IEqualityComparer<Fruit>
{
    public bool Equals(Fruit x, Fruit y)
    {
        return x?.Id == y?.Id;
    }

    public int GetHashCode(Fruit obj)
    {
        return obj.Id;
    }
}

The code works fine - but I wonder if that's the way to implement this interface?

What's the correct solution to implement an IEqualityComparer?

azzurro123
  • 521
  • 2
  • 10
  • 19

1 Answers1

2

That looks largely fine. You're open to a NullReferenceException if someone calls GetHashCode(null), although this is unlikely to happen. You should also make a habit of calling GetHashCode on the members of your type, although for an int that doesn't make any difference.

A good solution is:

public int GetHashCode(Fruit obj)
{
    if (obj is null)
        throw new ArgumentNullException(nameof(obj));

    return obj.Id.GetHashCode();
}

Expanding this to multiple properties is slightly more boilerplate-y, something such as:

public class FruitComparer : IEqualityComparer<Fruit>
{
    public bool Equals(Fruit x, Fruit y)
    {
        // Shortcut if they're the same object, and also handles the case
        // where they're both null
        if (ReferenceEquals(x, y))
            return true;

        // They're not both null. If either is null, they're not equal
        if (x is null || y is null)
            return false;

        // Neither is null. Compare properties.
        return x.First == y.First &&
            x.Second == y.Second; // Etc
    }

    public int GetHashCode(Fruit obj)
    {
        if (obj is null)
            throw new ArgumentNullException(nameof(obj));

        // Use the HashCode type to combine different properties' hashcodes
        return HashCode.Combine(obj.First, obj.Second);
    }
}
canton7
  • 37,633
  • 3
  • 64
  • 77