У меня возникают трудности с использованием метода 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()
.