Когда я должен использовать IEqualityComparer?C # - PullRequest
0 голосов
/ 23 октября 2018

У меня есть список пользовательских объектов, где я пытаюсь удалить дубликаты записей.Я вижу так много онлайн-статей, которые указывают на IEqualityComparer (я никогда не использовал это раньше).

Вопрос в том, когда мне его использовать?Я могу достичь того же результата с помощью LINQ в одной строке кода.

Пример:

public 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}
    };

    // Using Custom comparer
    var usingCustomComparer = products.Distinct(new ProductComparer()).ToList();

    // Using LINQ
    var usinLinq = products.GroupBy(x => x.Name).Select(y => y.First()).ToList();
}

public class Product
{
    public string Name { get; set; }
    public int Code { get; set; }
}

// Custom comparer for the Product class
private class ProductComparer : IEqualityComparer<Product>
{
    public bool Equals(Product x, Product y)
    {
        if (ReferenceEquals(x, y)) return true;

        if (ReferenceEquals(x, null) || ReferenceEquals(y, null)) return false;

        return x.Code == y.Code && x.Name == y.Name;
    }

    public int GetHashCode(Product product)
    {
        var hashProductName = product.Name == null ? 0 : product.Name.GetHashCode();

        var hashProductCode = product.Code.GetHashCode();

        return hashProductName ^ hashProductCode;
    }
}

Результат от обоих:

{Name = "apple", Code = 9},
{Name = "orange", Code = 4},
{Name = "lemon", Code = 12}

Ответы [ 3 ]

0 голосов
/ 23 октября 2018

В большинстве случаев сравнение может быть выполнено с некоторым количеством linq.Если оно одноразовое, выбор, скорее всего, зависит от личных предпочтений.

Если логика сравнения многократно используется, создание IEqualityComparer является стандартным и общеизвестным способом, принятым большинством API для сравнения двух объектов.Вы можете повторно использовать реализацию в методах, коллекциях и т. Д. Linq

0 голосов
/ 23 октября 2018

когда мне его использовать?

Некоторые возможности:

  • Когда ваше определение "равенства" сложнее, чем просто сравнение одного свойства
  • Когда вы хотите предварительно определить «равенство» для использования во многих запросах
  • Когда вы хотите определить «равенство» вне из Linq, например, при использовании класса в качествеключ к хеш-таблице
  • Если вы хотите немного изменить определение равенства без повторения кода (т.е. включить / выключить чувствительность к регистру)
0 голосов
/ 23 октября 2018

Исходя из вашего примера, скажем, что вы хотите сравнить объекты без учета регистра, чтобы «Apple» и «яблоко» считались одним и тем же объектом.Тогда ваш ProductComparer может выглядеть так:

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

        if (ReferenceEquals(x, null) || ReferenceEquals(y, null)) return false;

        return x.Code == y.Code && (x.Name.Equals(y.Name, StringComparison.InvariantCultureIgnoreCase));
    }

    public int GetHashCode(Product product)
    {
        var hashProductName = product.Name == null ? 0 : product.Name.ToLower().GetHashCode();

        var hashProductCode = product.Code.GetHashCode();

        return hashProductName ^ hashProductCode;
    }
}

И это даст результаты, отличные от Linq.

...