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