У меня возникают трудности с использованием метода Linq.Except() при сравнении двух коллекций настраиваемого объекта.
Я вывел свой класс из Object и реализовал переопределения для Equals(), GetHashCode() и операторов == и !=. Я также создал метод CompareTo().
В моих двух коллекциях, в качестве отладочного эксперимента, я взял первый элемент из каждого списка (который является дубликатом) и сравнил их следующим образом:
itemListA[0].Equals(itemListB[0]); // true
itemListA[0] == itemListB[0]; // true
itemListA[0].CompareTo(itemListB[0]); // 0
Во всех трех случаях результат такой, какой я хотел. Однако, когда я использую метод Linq Except(), дублирующие элементы не удаляются:
List<myObject> newList = itemListA.Except(itemListB).ToList();
Узнав о том, как Linq выполняет сравнения, я обнаружил различные (конфликтующие?) методы, которые говорят, что мне нужно наследовать от IEquatable<T> или IEqualityComparer<T> и т.д.
Я запутался, потому что, когда я наследую, например, IEquatable<T>, я должен предоставить новый метод Equals() другой подписью из того, что я уже переопределил. Должен ли я иметь два таких метода с разными сигнатурами, или мне больше не нужно выводить мой класс из Object?
Мое определение объекта (упрощенное) выглядит следующим образом:
public class MyObject : Object
{
public string Name {get; set;}
public DateTime LastUpdate {get; set;}
public int CompareTo(MyObject other)
{
// ...
}
public override bool Equals(object obj)
{
// allows some tolerance on LastUpdate
}
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 23 + Name.GetHashCode();
hash = hash * 23 + LastUpdate.GetHashCode();
return hash;
}
}
// Overrides for operators
}
Я заметил, что когда я наследую от IEquatable<T>, я могу сделать это с помощью IEquatable<MyObject> или IEquatable<object>; требования к изменению подписи Equals() при использовании одного или другого. Каков рекомендуемый способ?
То, что я пытаюсь выполнить:
Я хочу иметь возможность использовать Linq (Distinct/Except), а также стандартные операторы равенства (== и !=) без дублирования кода. Сравнение должно позволить двум объектам считаться равными, если их имя идентично, а свойство LastUpdate находится в пределах нескольких секунд (задано пользователем).
Edit:
Отображение кода GetHashCode().