Attempt #3 to simplify this question:
A generic List<T>
can contain any type - value or reference. When checking to see if a list contains an object, .Contains()
uses the default EqualityComparer<T>
for type T, and calls .Equals()
(is my understanding). If no EqualityComparer has been defined, the default comparer will call .Equals()
. By default, .Equals()
calls .ReferenceEquals()
, so .Contains()
will only return true if the list contains the exact same object.
Until you need to override .Equals()
to implement value equality, at which point the default comparer says two objects are the same if they have the same values. I can't think of a single case where that would be desirable for a reference type.
What I'm hearing from @Enigmativity is that implementing IEqualityComparer<StagingDataRow>
will give my typed DataRow a default equality comparer that will be used instead of the default comparer for Object
– allowing me to implement value equality logic in StagingDataRow.Equals()
.
Questions:
- Am I understanding that correctly?
- Am I guaranteed that everything in the .NET framework will call
EqualityComparer<StagingDataRow>.Equals()
instead ofStagingDataRow.Equals()
? - What should
IEqualityComparer<StagingDataRow>.GetHashCode(StagingDataRow obj)
hash against, and should it return the same value asStagingDataRow.GetHashCode()
? - What is passed to
IEqualityComparer<StagingDataRow>.GetHashCode(StagingDataRow obj)
? The object I'm looking for or the object in the list? Both? It would be strange to have an instance method accept itself as a parameter...
In general, how does one separate value equality from reference equality when overriding .Equals()
?
The original line of code spurring this question:
// For each ID, a collection of matching rows
Dictionary<string, List<StagingDataRow>> stagingTableDictionary;
StagingTableMatches.AddRange(stagingTableDictionary[perNr].Where(row => !StagingTableMatches.Contains(row)));
.