Какова рекомендуемая лучшая практика для использования IEqualityComparer <T>?

Обратитесь к этой ссылке Получить код ключа от нажатия клавиши и значения символа для любого кода клавиши

$('input#inp').keyup(function(e){
   $(this).val(String.fromCharCode(e.keyCode)); 
   $('div#output').html('Keycode : ' + e.keyCode);  
});

10
задан FishBasketGordo 14 December 2011 в 17:36
поделиться

5 ответов

Я сделал следующее, я не уверен, является ли это реальная лучшая практика, но это хорошо работало для меня.:)

public class GenericEqualityComparer<T> : IEqualityComparer<T>
{
    private Func<T, T, Boolean> _comparer;
    private Func<T, int> _hashCodeEvaluator;
    public GenericEqualityComparer(Func<T, T, Boolean> comparer)
    {
        _comparer = comparer;
    }

    public GenericEqualityComparer(Func<T, T, Boolean> comparer, Func<T, int> hashCodeEvaluator)
    {
        _comparer = comparer;
        _hashCodeEvaluator = hashCodeEvaluator;
    }

    #region IEqualityComparer<T> Members

    public bool Equals(T x, T y)
    {
        return _comparer(x, y);
    }

    public int GetHashCode(T obj)
    {
        if(obj == null) {
            throw new ArgumentNullException("obj");
        }
        if(_hashCodeEvaluator == null) {
            return 0;
        } 
        return _hashCodeEvaluator(obj);
    }

    #endregion
}

Затем можно использовать его в наборах.

var comparer = new GenericEqualityComparer<ShopByProduct>((x, y) => x.ProductId == y.ProductId);
var current = SelectAll().Where(p => p.ShopByGroup == group).ToList();
var toDelete = current.Except(products, comparer);
var toAdd = products.Except(current, comparer);

Если необходимо поддерживать пользовательский GetHashCode () функциональность, используйте альтернативного конструктора для обеспечения лямбды, чтобы сделать альтернативное вычисление:

var comparer = new GenericEqualityComparer<ShopByProduct>(
       (x, y) => { return x.ProductId == y.ProductId; }, 
       (x)    => { return x.Product.GetHashCode()}
);

Я надеюсь, что это помогает.=)

6
ответ дан 3 December 2019 в 15:54
поделиться

Я сказал бы, что лучшее использование будет состоять в том, когда необходимо будет включить различные правила равенства для определенного алгоритма. Очень таким же образом то, что алгоритм сортировки мог бы принять IComparer<T>, алгоритм открытия мог бы принять IEqualityComparer<T>

1
ответ дан 3 December 2019 в 15:54
поделиться

Список использует этот интерфейс много, таким образом, можно сказать a. Substract (b) или другие из этих хороших функций.

Просто помните: Если Вы - объекты, не возвращают тот же Хэш-код, Равняние не называют.

1
ответ дан 3 December 2019 в 15:54
поделиться

Это - то, что MSDN должен сказать о (неуниверсальном) IEqualityComparer:

Этот интерфейс позволяет реализацию специализированного сравнения равенства для наборов. Таким образом, можно создать собственное определение равенства и указать, что это определение используется с типом набора, который принимает IEqualityComparer интерфейс. В Платформе.NET, конструкторах Hashtable, NameValueCollection, и OrderedDictionary типы набора принимают этот интерфейс.

Этот интерфейс поддерживает только сравнения равенства. Настройка сравнений для сортировки и упорядочивания обеспечивается IComparer интерфейс.

Похоже, что универсальная версия этого интерфейса выполняет ту же функцию, но используется для Dictionary<(Of <(TKey, TValue>)>) наборы.

До лучших практик вокруг использования этого интерфейса в Ваших собственных целях. Я сказал бы, что лучшая практика должна будет использовать его, когда Вы получаете или реализуете класс, который имеет схожую функциональность к вышеупомянутым наборам платформы.NET и где Вы хотите добавить ту же возможность к своим собственным наборам. Это гарантирует, что Вы согласовываетесь с тем, как платформа.NET использует интерфейс.

Другими словами, поддерживайте использование этого интерфейса, если Вы разрабатываете пользовательский набор, и Вы хотите позволить Вашим потребителям управлять равенством, которое используется во многих LINQ и связанных с набором методах (например, Вид).

2
ответ дан 3 December 2019 в 15:54
поделиться

Каждый раз, когда вы думаете об использовании IEqualityComparer , задумайтесь, можно ли заставить класс реализовать IEquatable взамен. Если продукт всегда должен сравниваться по идентификатору, просто определите его как таковой, чтобы вы могли использовать компаратор по умолчанию.

Тем не менее, есть еще несколько причин, по которым вам может потребоваться индивидуальный comparer:

  1. Если существует несколько способов, которыми экземпляры класса могут считаться равными. Лучшим примером этого является строка, для которой фреймворк предоставляет шесть разных компараторов в StringComparer .
  2. Если класс определен таким образом, что вы не можете определить его как IEquatable . Это может включать классы, определенные другими, и классы, созданные компилятором (в частности, анонимные типы, которые по умолчанию используют сравнение по свойствам).

Если вы все же решите, что вам нужен компаратор, вы, безусловно, можете использовать обобщенный компаратор (см. Ответ DMenT), но если вам нужно повторно использовать эту логику, вы должны инкапсулировать ее в специальный класс. Вы даже можете объявить его, унаследовав от общей базы:

class ProductByIdComparer : GenericEqualityComparer<ShopByProduct>
{
    public ProductByIdComparer()
        : base((x, y) => x.ProductId == y.ProductId, z => z.ProductId)
    { }
}

Что касается использования, вы должны по возможности использовать компараторы. Например, вместо того, чтобы вызывать ToLower () для каждой строки, используемой в качестве ключа словаря (логика для которой будет разбросана по вашему приложению), вы должны объявить словарь для использования без учета регистра StringComparer . То же самое и с операторами LINQ, которые принимают средство сравнения. Но опять же,

12
ответ дан 3 December 2019 в 15:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: