8

2 つの int のリストを比較し、1 つの特定の値をワイルド カードとして扱いたいとします。

たとえば、-1 がワイルドカードの場合、

{1,2,3,4} == {1,2,-1,4} //returns true

そして、このすべてのロジックをラップするクラスを書いているのでIEquatable、関連するロジックを実装して持っていますpublic override bool Equals()

GetHashCodeしかし、オーバーライドする場合は多かれ少なかれ実装する必要があると常に考えていました.Equals()。コンパイラによって強制されていないことは確かですが、そうしないと間違っているという印象を受けました。

ただし、契約を破ることなく実装する方法がわかりません.GetHashCode()(Equal であるオブジェクトには異なるハッシュがあります)、または単に実装をreturn 1.

考え?

4

9 に答える 9

3

私が見る唯一の可能なアイデアは、少なくとも長さを利用することです。

public override int GetHashCode()
{
    return this.Length.GetHashCode()
}
于 2014-07-22T15:41:21.313 に答える
2

推奨されていますが、必須ではありません。のカスタム実装が必要ない場合はGetHashCode、実行しないでください。

于 2014-07-22T15:41:20.740 に答える
2

GetHashCode通常、クラスの要素をセットなどのある種のコレクションに格納する場合にのみ重要です。ここでそうである場合、@AlexDが指摘するように、平等はもはや推移的ではないため、一貫したセマンティクスを達成できるとは思いません。

たとえば、(整数リストではなく文字列グロブを使用して) 文字列 "A"、"B"、および "*" をセットに追加すると、追加した順序に応じて、セットは 1 つまたは 2 つの要素になります。それらの。

EquivalentTo()それが望ましくない場合は、等値をオーバーロードするのではなく、ワイルドカード マッチングを新しいメソッド (例: ) に入れることをお勧めします。

于 2014-07-22T15:48:16.690 に答える
1

X が Y と等しいことが観測され、Y が Z と等しいことが観測され、どの項目も変更されていない場合、XEquals(Object)IEquatable<T>.Equals(T)Z; さらに、X が Y に等しく、Y がZ に等しくない場合、X も Z にも等しくないと見なすことができます。ワイルドカードおよびファジー比較メソッドは等価関係を実装していないため、Equals一般にそのようなセマンティクスを実装するべきではありません。

Equals多くのコレクションは、同等の関係を実装しない方法で実装されたオブジェクトでちょっとした動作をします。ただし、2 つのオブジェクトが互いに等しいと比較すると、常に同じハッシュ コードが返されます。これを行うには、多くの場合、等しくないものを比較して同じハッシュ コードを返す必要がありますが、サポートされているワイルドカードの種類によっては、項目をある程度分けることができる場合があります。

たとえば、特定の文字列がサポートする唯一のワイルドカードが「1 つ以上の数字の任意の文字列」を表す場合、連続する数字のすべてのシーケンスおよび/または文字列のワイルドカード文字を単一の「文字列」に変換することにより、文字列をハッシュできます。 of digits」ワイルドカード文字。# が任意の数字を表す場合、文字列 abc123、abc#、abc456、および abc#93#22#7 はすべて abc# と同じ値にハッシュされますが、abc#b、abc123b などは別の値にハッシュされる可能性があります。価値。文字列の分布に応じて、このような区別によって、定数値を返すよりもパフォーマンスが向上する場合とされない場合があります。

GetHashCode等しいオブジェクトが等しいハッシュを生成するような方法で実装したとしても、等値メソッドが等価関係を実装していない場合、一部のコレクションは依然として奇妙な動作をする可能性があることに注意してください。たとえば、コレクションfooにキーが「abc1」と「abc2」の項目が含まれている場合、アクセスを試みるとfoo["abc#"]、最初の項目または 2 番目の項目が勝手に返される可能性があります。キー「abc#」を削除しようとすると、一方または両方のアイテムが任意に削除されるか、1 つのアイテムを削除した後で失敗する可能性があります (削除abc#後もコレクションに含まれるため、予期される事後条件が満たされない可能性があります)。

ジンクスEqualsを使ってハッシュ コードの等価性を比較しようとする代わりに、少なくとも 1 つのメイン コレクション文字列に一致する可能性のあるワイルドカード文字列ごとに、一致する可能性のある文字列のリストを保持する辞書を用意するという代替アプローチがあります。したがって、abc# に一致する文字列が多数ある場合、それらはすべて異なるハッシュ コードを持つ可能性があります。ユーザーが検索リクエストとして「abc#」を入力すると、システムはワイルドカード辞書で「abc#」を検索し、そのパターンに一致するすべての文字列のリストを受け取り、メイン辞書で個別に検索できます。 .

于 2014-07-22T20:41:22.380 に答える