3

これはC#にあります。キーがそこにあることを知っていても、Dictionary.ContainsKey が false を返すという問題があります。

残念ながら、表示するコードはありません。コードをまとめるのは簡単ではありません。複数のクラスに分散され、イベントなどによってトリガーされます。私が書いた簡単な単体テストでは、問題は再現されませんでした。

デバッグ セッション中の即時ウィンドウの出力を次に示します (コメントを追加し、詳細を保護するために変更しました)。

// throws KeyNotFoundException
myDict[key]  

// throws KeyNotFoundException
myDict[new MyKey("SomeString .1", "SomeOtherString", SomeEnum.Foo)]

// Element [5] is the key
myDict.Keys
Count = 10
    [0]: {...}
    [1]: {...}
    [2]: {...}
    [3]: {...}
    [4]: {...}
    [5]: {Foo SomeOtherString SomeString  .1}
    [6]: {...}
    [7]: {...}
    [8]: {...}
    [9]: {...}

// Get key at element [5]   
enumerator.Current
{Foo SomeOtherString SomeString  .1}
    [My.Namespace.KeyType]: {Foo SomeOtherString SomeString  .1}
    SomeEnum: Foo
    SomeOtherStringProperty: "SomeOtherString"

// key used to do lookup
key
{Foo SomeOtherString SomeString  .1}
    [My.Namespace.KeyType]: {Foo SomeOtherString SomeString  .1}
    SomeEnum: Foo
    SomeOtherStringProperty: "SomeOtherString"

// hash codes of key in dictionary matches hash code of lookup key
enumerator.Current.GetHashCode()
193014103
key.GetHashCode()
193014103

いくつかの追加メモ:

  • キーとして使用される型は、GetHashCode および Equals のメソッドをオーバーライドしています。
  • ディクショナリは、追加のコンストラクタ引数なしで new Dictionary() として構築されます。
  • デバッグにより、キー タイプの GetHashCode が呼び出されることを確認しましたが、Equals(obj) は呼び出されません。
  • アプリケーションを実行すると、キーの型を持つ DLL が 1 つだけ読み込まれるため、同じ DLL の異なるバージョンで同じ型が使用されることはおそらくありません。

なぜこれが起こっているのか誰にも分かりますか?

助けてくれてありがとう - 私はここでアイデアを使い果たしています.

4

1 に答える 1

4

キーとして使用される型は、GetHashCode および Equals のメソッドをオーバーライドしています。

これは私が最初に確認することです。ハッシュ コードが変更可能な値に基づいている場合、間違いなくこの問題が発生する可能性があります。

MSDNから:

一般に、変更可能な参照型の場合、次の場合にのみ GetHashCode をオーバーライドする必要があります。

  • 可変でないフィールドからハッシュ コードを計算できます。また

  • オブジェクトがそのハッシュ コードに依存するコレクションに含まれている間、変更可能なオブジェクトのハッシュ コードが変更されないようにすることができます。

そうしないと、変更可能なオブジェクトがハッシュ テーブルで失われたと考えるかもしれません。変更可能な参照型に対して GetHashCode をオーバーライドすることを選択した場合は、オブジェクトがハッシュ テーブルに格納されている間は、その型のユーザーがオブジェクトの値を変更してはならないことをドキュメントで明確にする必要があります。

于 2014-09-10T00:48:03.733 に答える