問題タブ [gethashcode]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
.net - GetHashCode をオーバーライドするための最適なアルゴリズムは何ですか?
.NET では、GetHashCode
メソッドは .NET 基本クラス ライブラリ全体の多くの場所で使用されます。これを適切に実装することは、コレクション内の項目をすばやく見つけたり、同等性を判断したりするときに特に重要です。
GetHashCode
パフォーマンスを低下させないように、カスタム クラスに実装する方法に関する標準アルゴリズムまたはベスト プラクティスはありますか?
.net - Object.GetHashCode() のデフォルトの実装
デフォルトの実装はどのように機能しますGetHashCode()
か? また、構造体、クラス、配列などを効率的かつ十分に処理できますか?
どのような場合に自分でパックする必要があるか、どのような場合にデフォルトの実装に安全に依存してうまくいくかを決定しようとしています. 可能であれば、車輪の再発明はしたくありません。
c# - GetHashCode 拡張メソッド
オーバーライドに関する StackOverflow のすべての質問と回答を読んだ後GetHashCode()
、簡単で便利なオーバーライドのために次の拡張メソッドを作成しましたGetHashCode()
。
(私は基本的に誰かがそこに投稿したコードをリファクタリングしただけです。なぜなら、それが一般的に使用できることが本当に好きだからです)
私はこのように使用します:
このコードに問題はありますか?
c# - C# Equals 契約に違反するクラスのハッシュコードを選択する方法は?
Equals
特定の理由で、公式の契約に従わない複数のクラスがあります。上書きGetHashCode()
されたこれらのクラスは単純に 0 を返すため、ハッシュマップで使用できます。
これらのクラスのいくつかは同じインターフェースを実装しており、このインターフェースをキーとして使用するハッシュマップがあります。だから私は、すべてのクラスが少なくとも異なる(しかしそれでも一定の)値を返す必要があると考えましたGetHashCode()
.
問題は、この値をどのように選択するかです。最初のクラスが 1 を返し、次のクラスが 2 というように単純に返す必要がありますか? または、次のようなものを試す必要があります
ハッシュはより均等に分散されますか?(返された値を自分でキャッシュする必要がありますか、それとも Microsoft のコンパイラでこれを最適化できますか?)
更新: Equals は規約に違反しているため、オブジェクトごとに個別のハッシュコードを返すことはできません。具体的には、この問題について言及しています。
c# - 可変オブジェクトの GetHashCode をオーバーライドしますか?
いつ、どのようにオーバーライドするかについて、約 10 の異なる質問を読みましたが、GetHashCode
まだよくわからないことがあります。のほとんどの実装はGetHashCode
、オブジェクトのフィールドのハッシュ コードに基づいていますが、 の値はGetHashCode
オブジェクトの存続期間にわたって変更されるべきではないとされています。それが基づいているフィールドが可変である場合、それはどのように機能しますか? また、オーバーライドされたものではなく、参照の等価性に基づいて辞書検索などを行いたい場合はどうすればよいEquals
ですか?
私は主にEquals
、シリアル化と逆シリアル化 (私の場合は XML へ) によって参照の等価性が失われると想定しているシリアル化コードの単体テストを容易にするためにオーバーライドしているため、少なくとも値の等価性によって正しいことを確認したいと考えています。この場合、オーバーライドEquals
するのは悪い習慣ですか? 基本的に、実行中のコードのほとんどで、参照の等価性が必要であり、常に使用==
しており、それをオーバーライドしていません。ValueEquals
オーバーライドする代わりに、新しいメソッドなどを作成する必要がありますEquals
か? 私は、フレームワークが常に物事を比較するために and を使用==
しないと想定していたEquals
ので、オーバーライドしても安全だと思っていEquals
ました。==
オペレーター。他のいくつかの質問を読むと、そうではないようです。
編集:
私の意図が不明確だったようです。私が言いたいのは、99% の時間は単純な古い参照の等価性、デフォルトの動作、驚きがないことを望んでいるということです。.Equals
非常にまれなケースですが、値の等価性が必要であり、代わりに を使用して値の等価性を明示的に要求したいと考えています==
。
これを行うと、コンパイラはオーバーライドGetHashCode
も推奨するため、この質問が出てきました。GetHashCode
変更可能なオブジェクトに適用する場合、次のような矛盾する目標があるように見えました。
- もしそう
a.Equals(b)
なら。a.GetHashCode()
== b.GetHashCode()
- の値は
a.GetHashCode()
、 の存続期間中は変更されませんa
。
オブジェクトの状態が変化すると、 の値が変化することが予想されるため、これらは当然矛盾しているように.Equals()
見えGetHashCode
ます。.Equals()
GetHashCode
なぜこのような矛盾があるように見えるのでしょうか? これらの推奨事項は、変更可能なオブジェクトに適用するためのものではありませんか? おそらく想定されていますが、構造体ではなくクラスについて言及していることに言及する価値があるかもしれません。
解像度:
私は JaredPar を承認済みとしてマークしていますが、主にコメントのやり取りのためです。ここから学んだことをまとめると、すべての目標を達成し、エッジ ケースで発生する可能性のある風変わりな動作を回避する唯一の方法は、オーバーライドEquals
しGetHashCode
て不変フィールドに基づくか、または を実装することIEquatable
です。Equals
この種の参照型は、主キーでそれらを識別するためにリレーショナル データベースに格納されていない限り、ほとんどの参照型は通常、不変フィールドを持たないことがわかっているため、参照型のオーバーライドの有用性を損なうようです。
c# - Equals メソッド実装ヘルパー (C#)
データ クラスを作成するたびに、IEquatable の実装に多くの時間を費やします。
私が書いた最後のクラスは次のようなものでした:
IEquatable の実装は非常に困難でした。確かに C#3.0/LINQ は大いに役立ちますが、頂点をシフトしたり、逆の順序にしたりできるため、Equals メソッドが非常に複雑になります。多くの単体テストと対応する実装の後、あきらめて、アプリケーションを三角形のみを受け入れるように変更しました。IEquatable の実装では、11 個の単体テストのみを完全にカバーする必要がありました。
Equals と GetHashCode の実装に役立つツールまたは手法はありますか?
c# - xor を使用した GetHashCode() の問題
私の理解では、通常、GetHashCode() で xor を使用して int を生成し、(参照ではなく) その値でデータを識別します。簡単な例を次に示します。
アイデアは、プロパティ A と B の値に基づいて、ある Foo のインスタンスを別のインスタンスと比較したいということです。
問題は次のとおりです。
これらは両方とも、GetHashCode() に対して 3 の値を生成し、Equals() が true を返すようにします。明らかに、これは簡単な例であり、プロパティが 2 つしかないので、Equals() メソッドで個々のプロパティを簡単に比較できます。ただし、より複雑なクラスでは、これはすぐに手に負えなくなります。
ハッシュ コードを 1 回だけ設定し、常に同じ値を返すことが理にかなっている場合があることを私は知っています。ただし、等価性の評価が必要な可変オブジェクトの場合、これは合理的ではないと思います。
GetHashCode() を実装するときに簡単に交換できるプロパティ値を処理する最良の方法は何ですか?
関連項目
c# - 複雑な等価性のために Object.GetHashCode() を実装するにはどうすればよいですか?
基本的に、私はこれまでのところ以下を持っています:
したがって、問題は次のとおりですGuid
。一意の識別子である必須ではないフィールドがあります。これが設定されていない場合は、2 つのオブジェクトが等しいかどうかを判断する試みとして、精度の低いメトリックに基づいて等しいかどうかを判断する必要があります。これはうまくいきますが、GetHashCode()
面倒になります...どうすればいいですか?単純な実装は次のようになります。
しかし、2 種類のハッシュが衝突する可能性はどのくらいでしょうか? 確かに、そうなるとは思いません1 in 2 ** 32
。これは悪い考えですか? もしそうなら、どうすればいいですか?