I needed to find the difference between the two collections , the elements of the collection are instances of the user class.

To find the difference, I want to use the linq method Except , the method description says that for user types you need to do one of two things:

Inherit the custom class from IEquatable<T> and override the Equals & GetHashCode methods in the source class.

 public class OperationItem: IEquatable<OperationItem> { public bool Equals(OperationItem other) { if (other is null) return false; return this.Name == other.Name && this.Code == other.Code; } public override bool Equals(object obj) => Equals(obj as OperationItem); public override int GetHashCode() => (Name, Code).GetHashCode(); } 

Or create the comparator we need by implementing the IEqualityComparer<T> interface and implementing the Equals & GetHashCode methods we already know.

 public class OperationItemComparer: IEqualityComparer<OperationItem> { public bool Equals(OperationItem x, OperationItem y) { /*Реализация*/ } public int GetHashCode(OperationItem obj) { /*Реализация*/ } } 

Is there a significant difference in the use of this or that method, I assume that the second method is used in case of impossibility to change the original class, but maybe there are other reasons for using one or another method?

  • For example, if in different situations the equality of your objects is determined differently. Or, for example, if you do not want to dirty your classes with some sort of logic. - tym32167
  • those. Is this or that method determined by the ability / desire to make changes to the original class and the need to implement several comparison methods? - Bald
  • In fact, yes, it is - tym32167
  • It seems that if you do not override the default, then the comparison of links will be used. - trollingchar
  • public override bool Equals (object obj) - not the method you override, in the interface it accepts a specific type and not an object - Grundy

1 answer 1

The IEquatable<> implementation of the interface type adds an equivalence relation as a natural property of the type itself. After that, any collections and any algorithms will use this relation by default!

From here several restrictions follow: the Equals and GetHashCode methods must necessarily take into account all the properties of the class in order to avoid surprises in the future. In addition, these methods cannot take into account any extraneous data not related to the object being checked.

At the same time, the implementation of the IEqualityComparer<> adds some equivalence relation that you can use and not use. This implementation can generally be private and used all in one place. This implementation can take into account some external settings (for example, the StringComparer from the standard library allows you to specify how to compare strings). Finally, there may be many such implementations, and they will not interfere with each other.

  • From here several restrictions follow: the Equals and GetHashCode methods must necessarily take into account all the properties of the class in order to avoid surprises in the future. meaning that the implementation of the methods is probably not all the properties , but those on the basis of which the uniqueness of the instance is determined? - Bald
  • @Bald and what is a "property that does not define uniqueness"? - Pavel Mayorov
  • In my particular case, this class is a class that describes a table in the database, and in this case, only the Id properties are enough for me to check, but there are other properties in the table - Bald
  • @Bald suppose you for some reason have two objects with one Id , but different data. For example, these are two versions of the same record. Is it possible to say that these two objects are equal? - Pavel Mayorov
  • This example shows that when comparing objects you need to take into account the Id & Version number ? it is clear that you can check all the fields , I used to think that not. I am wrong? - Bald