1

次のような辞書があります。

var dic = Dictionary<Collection<MyObject>, string>

次に、次のようなエントリを追加します。

dic.Add(myObjColl, "1");

myObjColl には単一のエントリが含まれます

2 回目の実行で、myObjColl に 2 つのエントリ (そのうちの 1 つは最初の実行と同じ) がある dic に別のエントリを追加しようとすると、キーが既に存在するという例外が発生します。

ここで何が欠けていますか?ディクショナリ キーはコレクションであると予想されますが、エントリ数が異なる 2 つのコレクションは同一ではありません。

編集:何が起こったのかというと、myObjColl が foreach の外で初期化され、2 回目の反復中に更新されました。だから、2つのエントリを持つ新しいコレクションだと思っていたのは、実際には古い1つのエントリのコレクションに追加のエントリが追加されたものでした.

私の問題について少し詳しく説明するには:

製品行オブジェクトのコレクションがあります。それぞれに、キーと値のペアのコレクションで構成される製品識別オブジェクトがあります。

Collection<ProductKeyValuePair> productIdentification;
myProductRow.ProductIdentification = productIdentification;

次に、各製品行オブジェクトの「所有者」を定義する ProductKeyValuePairs の別のコレクションを作成する必要があり (1 つの製品行オブジェクトは複数の所有者を持つことができます)、各所有者を対応する製品行オブジェクトに追加する必要があります。共通キーが KeyValuePairs のコレクションである従来の多対多。

説明するのは難しいですが、メインフレームで実行されている古いシステムから返され、おそらく何らかの階層型データベースに保存されているレガシー データにかかっています :-/

4

3 に答える 3

6

辞書のキーは、キーとしての役割を果たしている間は不変であることが期待されます。GetHashCode()またはの値を変更するために何かを行うEquals(object)と、未定義の動作が発生します。

(また、Collection実装せずGetHashCode()Equals(object)含まれているメンバーを使用する場合は、コンテナー オブジェクト自体への参照による比較のみを行います)

于 2013-08-09T07:22:13.957 に答える
2

コレクションの内容を調べているわけではありません。

それは単にmyObjColl(refによって)キーとして使用しています。

注: コレクションをキーとして持つことは非常にまれです。キーは通常、文字列 (または整数) です。

于 2013-08-09T07:21:49.377 に答える
0

コレクションのような参照型をディクショナリのキーにするには、通常、カスタムの比較子 ( IEqualityComparer<TKey>) をディクショナリのコンストラクタに渡す必要があります。それ以外の場合、通常は値セマンティックを持たないクラスのデフォルトEquals/実装が使用されます (つまり、値のように動作する参照型のサンプルです)。GetHashCodestring

コレクション (null チェックなし、カウントのみを比較) および以下の使用法のための過度に単純化された比較子:

class ListSameByCount<T> : EqualityComparer<List<T>>
{

  public override bool Equals(List<T> b1, List<T> b2)
  {
    return b1.Count() == b2.Count();
  }

  public override int GetHashCode(List<T> b1)
  {
    return b1.Count().GetHashCode();
  }
}

var dictionary = new Dictionary<List<int>, int>(new ListSameByCount<int>());

注: コレクションは、変更 (アイテムの追加/削除/変更) される可能性があり、結果としてハッシュ コードが変更され、辞書がキーを見つけることができなくなるため、辞書のキーの候補として不適切なことがよくあります。

于 2013-08-09T07:39:18.187 に答える