I'm having some difficulty using Linq's .Except() method when comparing two collections of a custom object.
I've derived my class from Object and implemented overrides for Equals(), GetHashCode(), and the operators == and !=. I've also created a CompareTo() method.
In my two collections, as a debugging experiment, I took the first item from each list (which is a duplicate) and compared them as follows:
itemListA[0].Equals(itemListB[0]); // true
itemListA[0] == itemListB[0]; // true
itemListA[0].CompareTo(itemListB[0]); // 0
In all three cases, the result is as I wanted. However, when I use Linq's Except() method, the duplicate items are not removed:
List<myObject> newList = itemListA.Except(itemListB).ToList();
Learning about how Linq does comparisons, I've discovered various (conflicting?) methods that say I need to inherit from IEquatable<T> or IEqualityComparer<T> etc.
I'm confused because when I inherit from, for example, IEquatable<T>, I am required to provide a new Equals() method with a different signature from what I've already overridden. Do I need to have two such methods with different signatures, or should I no longer derive my class from Object?
My object definition (simplified) looks like this:
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
}
I noticed that when I inherit from IEquatable<T> I can do so using IEquatable<MyObject> or IEquatable<object>; the requirements for the Equals() signature change when I use one or the other. What is the recommended way?
What I am trying to accomplish:
I want to be able to use Linq (Distinct/Except) as well as the standard equality operators (== and !=) without duplicating code. The comparison should allow two objects to be considered equal if their name is identical and the LastUpdate property is within a number of seconds (user-specified) tolerance.
Edit:
Showing GetHashCode() code.