封印されていない型は を実装すべきではありませんIEquatable<T>
。派生型がそれを正しく実装することを保証する (またはその可能性を高める) 唯一の方法は、IEquatable<T>.Equals(T)
を呼び出すように実装することだからObject.Equals(Object)
です。の全体的な目的は、物事を比較する前にIEquatable<T>
変換して CPU 時間を浪費するのを避けることであるため、 を呼び出す実装は、インターフェースが実装されていない場合に達成されるデフォルトの動作よりも速く何もできませんでした。Object
Object.Equals(Object)
シールされたクラス型は、実装することでパフォーマンスがわずかに向上する場合がありIEquatable<T>
ます。推奨されるスタイルはObject.Equals(Object)
、パラメーターを にキャストしようとすることT
です。キャストが成功した場合は、IEquatable<T>.Equals
実装を使用します。それ以外の場合は返品しfalse
ます。同じオブジェクト インスタンスを渡したときに、異なる結果が得られるべきIEquatable.Equals(T)
ではありません。Object.Equals(Object)
構造体型は、sealed クラス型と同じパターンを使用できます。失敗したキャストは を返すことができないため、キャストを試みる方法は少し異なりますnull
が、パターンは同じである必要があります。構造体が変更インターフェースを実装する場合 (たとえばList<T>.Enumerator
、 を実装する構造体の場合のようにIEnumerator<T>
)、等値比較の適切な動作は少しあいまいです。
ところで、IComparable<T>
とIEquatable<T>
は互いに独立していると見なされるべきであることに注意してください。when X.CompareTo(Y)
is zeroX.Equals(Y)
が true を返す場合がよくありますが、一部の型は自然な順序付けを持ち、2 つのものが互いにランク付けされずに異なる場合があります。たとえば、 aと aNamedThing<T>
を組み合わせた型があるとします。そのようなタイプは、名前の自然な順序付けをサポートしますが、必ずしもそうではありません。名前は一致するが が異なる 2 つのインスタンスは、 for を返しますが、 forを返します。このため、 が変更されていない場合、オーバーライドはオーバーライドを必要としません。string
T
T
T
0
CompareTo
false
Equals
IComparable
GetHashCode
Equals