Equality comparator inheritance

I have a Customer class.

public class Customer
{
    private string _id;
    private string _name;
    // some more properties follow 

      

I inherit the EqualityComparer form MyEqualityComparer (from the client).
This is what I intend to use in LINQ queries.
MyEqualityComparer is for partial validation between two objects.
If customer.id and customer.name are the same, I treat the objects as equal.

public class MyComparer : System.Collections.Generic.EqualityComparer<Customer>
{
    public override bool Equals(Customer x, Customer y)
    {
        if (x.Id == y.Id && x.Name == y.Name)
            return true;
        else
            return false;
    }

    public override int GetHashCode(Customer obj)
    {
        return string.Concat(obj.Id,obj.Name).GetHashCode();
    }

}

      

I have referenced generating hashcode .
I'm not sure about string concatenation and using this as a hash code. Is this safe and reliable what I am trying to do?

+1


source to share


3 answers


See this hashcode question for a pretty simple way to return a single hashcode based on multiple fields.

Having said that, I wouldn't get it myself EqualityComparer<T>

- I would just implement IEqualityComparer<T>

directly. I'm not sure what value it EqualityComparer<T>

really gives you here, other than implementing a non-generic one IEqualityComparer

.

A couple more things:



  • You have to handle nullity in Equals
  • The existing Equals code can be simplified to:

    return x.Id == y.Id && x.Name == y.Name;
    
          

A more complete implementation of Equals could be:

public override bool Equals(Customer x, Customer y)
{
    if (object.ReferenceEquals(x, y))
    {
        return true;
    }
    if (x == null || y == null)
    {
        return false;
    }
    return x.Id == y.Id && x.Name == y.Name;
}

      

+5


source


You should see this in terms of possible "collisions", for example. when two different objects get the same hashcode. This can be the case with pairs such as "1,2any" and "12, any", the values ​​in the pairs are "id" and "name". If that's not possible with your data, you're good to go. Otherwise, you can change it to something like:



return obj.Id.GetHashCode() ^ obj.Name.GetHashCode();

      

+3


source


Resharper (a fantastic refactoring plugin from JetBrains) thinks it should be:

public override int GetHashCode(Customer obj)
{
    unchecked
    {
        return ((obj.Id != null ? obj.Id.GetHashCode() : 0) * 397) 
            ^ (obj.Name != null ? obj.Name.GetHashCode() : 0);
    }
}

      

I must admit that I almost always just let Resharper generate the equality and hash code implementation for me. I have tested their implementations a lot and find them to be as good, if not better, than anything I write by hand. So I usually take an implementation that I don't need to type.

+1


source







All Articles