Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I would generally recommend against implementing IEquatable&lt;T&gt; on any non-sealed class, or implementing non-generic IComparable on most, but the same cannot be said for IComparable&lt;T&gt;. Two reasons:</p> <ol> <li>There already exists a means of comparing objects which may or may not be the same type: Object.Equals. Since IEquatable&lt;T&gt; does not include GetHashCode, its behavior essentially has to match that of Object.Equals. The only reason for implementing IEquatable&lt;T&gt; in addition to Object.Equals is performance. IEquatable&lt;T&gt; offers a small performance improvement versus Object.Equals when applied to sealed class types, and a big improvement when applied to structure types. The only way an unsealed type's implementation of IEquatable&lt;T&gt;.Equals can ensure that its behavior matches that of a possibly-overridden Object.Equals, however, is to call Object.Equals. If IEquatable&lt;T&gt;.Equals has to call Object.Equals, any possible performance advantage vanishes. <li>It is sometimes possible, meaningful, and useful, for a base class to have a defined natural ordering involving only base-class properties, which will be consistent through all subclasses. When checking two objects for equality, the result shouldn't depend upon whether one regards the objects as being a base type or a derived type. When ranking objects, however, the result should often depend upon the type being used as the basis for comparison. Derived-class objects should implement IComparable&lt;TheirOwnType&gt; but should not override the base type's comparison method. It is entirely reasonable for two derived-class objects to compare as "unranked" when compared as the parent type, but for one to compare above the other when compared as the derived type. </ol> <p>Implementation of non-generic IComparable in inheritable classes is perhaps more questionable than implementation of IComparable&lt;T&gt;. Probably the best thing to do is allow a base-class to implement it if it's not expected that any child class will need some other ordering, but for child classes not to reimplement or override parent-class implementations.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. COI know this is an old topic, but still: I don't think your first point is true at all. object.Equals checks for reference equality, so the main reason for implementing IEquatable<T> in my opinion is to change that behavior and check for value equality instead (or however equality is defined for a certain type). As to performance: I have no proof of this, but I'm pretty sure that object.Equals beats most if not all self-made implementations since it only checks for reference equality (only on reference types of course).
      singulars
    2. CO@enzi: The static `Object.Equals` method performs a reference-equality check only if at least one argument is null. Otherwise it calls the first object's override of `Object.Equals`. Both that override of `Object.Equals` and the implementation of `IEquatable<T>.Equals`, if any, are expected to be consistent with `GetHashCode()`, which implies that unless `GetHashCode()` returns a constant, the two `Equals` methods must return somewhat-consistent results. If either `Equals` method test reference equality, both must do so.
      singulars
    3. CO@enzi: Are you perhaps confused by the use of the term `Object.Equals` to refer to the overridable method, as opposed to the default implementation thereof? Would some other notation be clearer? Given `Sillier:Silly:Foo`, where `Foo` and `Sillier` declare `public override bool Equals(Object Other)` and `Silly` declares `public new virtual bool Equals(Object Other)`. Then for a `Sillier` instance, I would say that `Foo` overrides `Object.Equals` and `Sillier` overrides `Silly.Equals`. There *shouldn't be* any `Equals(Object)` other than `Object.Equals`, but I use the term `Object.Equals`...
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload