繁体   English   中英

集合作为字典中的关键字

[英]Collection as key in Dictionary

我有一本这样的字典:

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

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

dic.Add(myObjColl, "1");

其中myObjColl包含一个条目

在第二次运行中,我尝试将另一个条目添加到dic中,其中myObjColl具有两个条目(其中一个与第一次运行中的条目相同),并且我得到一个例外,表明密钥已经存在。

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

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

详细说明我的问题:

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

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

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

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

字典中的键在履行其作为键的作用时应该是不变的。 如果您做任何更改GetHashCode()Equals(object)的值的操作,则将得到未定义的行为。

(同样,如果Collection没有实现GetHashCode()Equals(object)来使用其包含的成员,则仅通过引用容器对象本身来进行比较)

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

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

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

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

过于简化的收集器比较器(没有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>());

注意:集合在字典中通常不适合作为键的候选者,因为它们可能会发生突变(添加/删除/更改的项目),结果哈希码将更改,并且字典将无法找到键。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM