In LINQ’s Except Method #1, we went over GetHashCode in depth. In this blog, we will go over a special scenario on how to implement IEqualityComparer to be used in LINQ’s Except method.

public static IEnumerable Except(
    this IEnumerable first,
    IEnumerable second,
    IEqualityComparer comparer
)

MSDN provides an implementation reference [1]. To implement IEqualityComparer, we have to provide the implementation for Equals and GetHashCode. The example is enough for normal scenarios.

But what if we have this additional business requirement, we want to know the exact differences of products being compared in the same category, and don’t care to know the differences of products in different categories. For example, we know that Product { Name = “orange”, Code = 4} is in Except. In addition,

  1. We also want to know the difference between Product { Name = “orange”, Code = 4} of fruits1 and Product { Name = “orange”, Code = 8} of fruits2. These two products are in the same category.
  2. However, we don’t care the differences among orange and other fruits, and we also don’t want to waste resource to compare them.
            
            Product[] fruits1 = 
            {
                new Product { Name = "apple", Code = 9},
                new Product { Name = "orange", Code = 4},
                new Product { Name = "plum", Code = 4},
                new Product { Name = "apple", Code = 9},
                new Product { Name = "lemon", Code = 12}
            };

            Product[] fruits2 = 
            {                
                new Product { Name = "banana", Code = 11},
                new Product { Name = "lemon", Code = 14},
                new Product { Name = "orange", Code = 8},
                new Product { Name = "lemon", Code = 14},                
                new Product { Name = "apple", Code = 9},
                new Product { Name = "pineapple", Code = 12}
            };

In this case, we have to modify GetHashCode and Equals methods.

        // If Equals() returns true for a pair of objects 
        // then GetHashCode() must return the same value for these objects.
        public int GetHashCode(Product product)
        {            
             return product.Name.GetHashCode();        
        }

By using the product.Name’s hash code, we try to balance the distribution of each bucket. If they are the same products, the comparison then will use Equals to check further conditions, and satisfy the additional business requirement.

For the full implementation of Equals and exploration of Except / IEqualityComparer, please refer to this link in my GitHub. I suggest you down load the code, run, change the codes, and find out what’s really going on. There is tons of information I skip due to time constraints.

References:

  1. Enumerable.Except
Advertisements