2 つのインスタンスが与えられ、それぞれが同じ内容を持ち、任意の順序で挿入できるDictionary<long, string>
コレクションを使用する必要があります。d1
d2
KeyValuePair<long, string>
(d1 == d2)
に評価されますtrue
d1.GetHashCode()
==d2.GetHashCode()
最初の要件はSortedDictionary
、通常の の代わりに を使用することで最も簡単に達成できましたDictionary
。
2 番目の要件が必要なのは、保存する必要がある 1 つのポイントがあるためですDictionary<Dictionary<long, string>, List<string>
。メインのDictionary
型は別のキーとして使用されDictionary
、HashCodes が同一の内容に基づいて評価されない場合、使用は希望どおりに機能しませんContainsKey()
。 (つまりd1
、 をキーとして辞書に挿入されたアイテムが既に存在する場合は、dictionary.ContainsKey(d2)
と評価される必要がありtrue
ます。
これを実現するために、新しいオブジェクトを作成しclass ComparableDictionary : SortedDictionary<long, string>
、次のものを含めました。
public override int GetHashCode() {
StringBuilder str = new StringBuilder();
foreach (var item in this) {
str.Append(item.Key);
str.Append("_");
str.Append(item.Value);
str.Append("%%");
}
return str.ToString().GetHashCode();
}
私の単体テストでは、これは等価性とハッシュコードの両方の基準を満たしています。ただし、GetHashCode のガイドラインとルールを読んでいると、次のことに気付きました。
規則: GetHashCode によって返される整数は、オブジェクトがハッシュ コードが安定していることに依存するデータ構造に含まれている間、決して変更してはなりません。
危険ではありますが、オブジェクトのフィールドが変化するにつれてハッシュ コード値が変化する可能性があるオブジェクトを作成することは許容されます。そのようなオブジェクトがあり、それをハッシュテーブルに入れる場合、オブジェクトを変更するコードとハッシュテーブルを維持するコードには、オブジェクトが存在している間に変更されないことを保証する合意されたプロトコルが必要です。ハッシュテーブル。そのプロトコルがどのように見えるかはあなた次第です。
オブジェクトのハッシュ コードがハッシュ テーブル内にある間に変化する可能性がある場合、明らかに、Contains メソッドは機能しなくなります。オブジェクトをバケット #5 に入れ、それを変更します。セットに変更されたオブジェクトが含まれているかどうかを尋ねると、セットはバケット #74 を探しますが、見つかりません。
オブジェクトは、予期しない方法でハッシュ テーブルに配置される可能性があることを覚えておいてください。多くの LINQ シーケンス演算子は、ハッシュ テーブルを内部的に使用します。オブジェクトを返す LINQ クエリを列挙しているときに、危険なほどオブジェクトを変更しないでください。
現在、 は、すべてのコレクションDictionary<ComparableDictionary, List<String>>
の内容を設定する必要がある場所で、コード内で 1 回だけ使用されます。ComparableDictionary
したがって、これらのガイドラインによれば、私が行ったように (完全に辞書の内容に基づいて)オーバーライドすることは許容されると思います。GetHashCode
その紹介の後、私の質問は次のとおりです。
SortedDictionary
に比べてのパフォーマンスが非常に悪いことはわかっていますDictionary
(そして、何百ものオブジェクトのインスタンス化を行うことができます)。使用する唯一の理由SortedDictionary
は、挿入の順序に関係なく、辞書の内容に基づいて等価比較を機能させるためです。を使用せずにこの平等要件を達成するためのより良い方法はありSortedDictionary
ますか?- の実装は
GetHashCode
要件に基づいて受け入れられますか? 変更可能なコンテンツに基づいていますが、それが使用されている場所はコンテンツが設定された後 (だと思います) だけなので、それはリスクをもたらすべきではないと思います。
注Dictionary
:またはを使用してこれらを設定している間SortedDictionary
、私はこれらのコレクション型に執着していません。主な必要性は、値のペアを格納できるコレクションであり、上記で定義された等価性とハッシュの要件を満たします。