Что-то не пойму с Distinct

Пытаюсь избавится от повторов сравнивая по конкретному полю объекта Взял код из MSDN немного изменив

 static void Main(string[] args)
    {
        Product[] products = {
            new Product { Name = "apple", Code = 9 },
            new Product { Name = "orange", Code = 4 },
            new Product { Name = "apple", Code = 9 },
            new Product { Name = "lemon", Code = 12 },
            new Product { Name = "lemon", Code = 32 },
            new Product { Name = "lemon", Code = 9 }};

        IEnumerable<Product> noduplicates =
            products.Distinct(new ProductComparer());

        foreach (var product in noduplicates)
            Console.WriteLine(product.Name + " " + product.Code);
    }
    public class Product
    {
        public string Name { get; set; }
        public int Code { get; set; }
    }

    class ProductComparer : IEqualityComparer<Product>
    {         
        public bool Equals(Product x, Product y)
        {   
            if (Object.ReferenceEquals(x, y)) return true;                             
            if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
                return false;

            return x.Code == y.Code;
        }

        public int GetHashCode(Product product)
        {             
            if (Object.ReferenceEquals(product, null)) return 0;

            int hashProductName = product.Name == null ? 0 : product.Name.GetHashCode();                
            int hashProductCode = product.Code.GetHashCode();

            return hashProductName ^ hashProductCode;
        }
    }

Так вот если ставить точку прерывания на Equals, то попадаешь туда только один раз на сравнении Product { Name = "apple", Code = 9 }. Соответственно и результат не совсем ожидаемый, отбрасывается только один из Product { Name = "apple", Code = 9 } Пример надуманный естественно. Просто непонятно почему Distinct не вызывается для всех объектов?! Как оно вообще работает?!


Ответы (1 шт):

Автор решения: CrazyElf

Как правильно написали в комментарии, сравнивать объекты - дело затратное, поэтому сначала сравнивается хэш-код объектов и если он разный, то объекты сразу же считаются разными. Если же хэш-код объектов совпал, то только тогда сравниваются собственно объекты (потому что у хэш-кода бывают коллизии - одинаковые значения при разном значении объектов). Обратная ситуация, когда хэш-код разный, а объекты при этом одинаковые - невозможна в силу детерминированности функции вычисления хэш-кода по объекту.

→ Ссылка