集合作为字典中的关键字

本文关键字:关键字 字典 集合 | 更新日期: 2023-09-27 18:27:03

我有一本这样的字典:

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

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

dic.Add(myObjColl, "1");

其中myObjColl包含单个条目

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

我在这里错过了什么?我希望字典键是一个集合,当然两个条目数不同的集合不可能是相同的。

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

详细阐述一下我的问题:

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

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

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

很难解释,但这实际上取决于从大型机上运行的旧系统返回的遗留数据,这些数据很可能存储在某种层次数据库中:-/

集合作为字典中的关键字

字典中的键在充当键时应是不可变的。如果您更改GetHashCode()Equals(object)的值,您将得到未定义的行为。

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

它不是在检查集合的内容。

它只是简单地使用myObjColl(通过ref)作为密钥。

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

要使引用类型(如集合)成为字典中的键,通常需要将自定义比较器(IEqualityComparer<TKey>)传递给字典的构造函数。否则,将使用类的默认Equals/GetHashCode实现,该实现通常不具有值语义(例如,string是行为类似值的引用类型的示例)。

过度简化了收集比较器(没有空检查,只比较计数)和以下用法:

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>());

注意:集合通常不适合字典中的关键字,因为它们可能会发生变化(添加/删除/更改项),因此哈希代码会发生变化,字典将无法找到关键字。