1

我有一本这样的字典:

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

然后我添加一个这样的条目:

dic.Add(myObjColl, "1");

其中 myObjColl 包含单个条目

在第二次运行时,我尝试向 dic 添加另一个条目,其中 myObjColl 有两个条目(其中一个与第一次运行中的条目相同)并且我得到一个密钥已经存在的异常。

我在这里想念什么?我希望字典键是一个集合,并且具有不同条目数的两个集合肯定不能相同。

编辑:发生的事情是 myObjColl 在 foreach 外部初始化并在第二次迭代期间更新。所以我认为是一个包含两个条目的新集合实际上是旧的一个条目集合,添加了一个额外的条目。

详细说明我的问题:

我有一个产品行对象的集合。每个都有一个由键值对集合组成的产品标识对象:

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

然后,我必须构建另一个 ProductKeyValuePairs 集合,定义每个产品行对象的“所有者”(一个产品行对象可以有多个所有者),并且我需要将每个所有者添加到相应的 procuct 行对象中。传统的多对多,其中公共密钥是 KeyValuePair 的集合。

很难解释,但这实际上归结为从大型机上运行的旧系统返回的遗留数据,并且很可能存储在某种分层数据库中:-/

4

3 回答 3

6

字典中的键在执行其作为键的角色时应该是不可变的。如果你做任何事情来改变GetHashCode()orEquals(object)你会得到未定义的行为。

(如果Collection没有实现GetHashCode()Equals(object)使用它包含的成员,它只会通过引用容器对象本身进行比较)

于 2013-08-09T07:22:13.957 回答
2

它不是检查集合的内容。

它只是使用myObjColl(by ref) 作为键。

注意:将集合作为键是非常不寻常的。键通常是字符串(或整数)。

于 2013-08-09T07:21:49.377 回答
0

要让像集合这样的引用类型成为字典中的键,您通常需要将自定义比较器 ( IEqualityComparer<TKey>) 传递给字典的构造函数。否则,使用通常不具有值语义的类的默认Equals/实现(即行为类似于值的引用类型的样本)。GetHashCodestring

过度简化的收集比较器(无空检查,仅比较计数)和以下用法:

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 回答