c# - 非基于哈希的集合集合,用于使用自定义相等比较器存储唯一对象 - C#

标签 c# collections set unique iequalitycomparer

我正在尝试将(名称:字符串,值:长)对存储在一个集合中。

public class NameValuePair
{
  public string name;
  public long value;
}

public NameValuePairComparer comparer = new NameValuePairComparer();
public HashSet<NameValuePair> nameValueSet = new HashSet<NameValuePair>(comparer);

如果两个对具有相同的名称或相同的值,则它们相等 - 这是在 NameValuePairComparer 中实现的,重写 EqualityComparer 中的 Equals 方法:

public class NameValuePairComparer : EqualityComparer<NameValuePair>
{
   public override bool Equals(NameValuePair x, NameValuePair y)
   {
      return (x.value == y.value) || (x.name == y.name);
   }

问题是:GetHashCode(NameValuePair obj) 对于 Equals 返回 true 的两个对象应该返回相同的值,因此对于给定的 NameValuePair,GetHashCode() 应该返回 value.GetHashCode() 或 name.GetHashCode(),但是为此,我们必须知道两对中的哪个字段相等:

   public override int GetHashCode(NameValuePair obj)
   {
      /* ??? */
      /* // Using unknown reference to x
        if (obj.value == x.value) return obj.value.GetHashCode();
        else if (obj.name == x.name) return obj.name.GetHashCode();
        else return base.GetHashCode(obj);
      */
   }
}

但是我们无法知道这一点,这意味着我无法使用 HashSet 来存储这些对,也无法使用 EqualityComparer。

问:C# (.net 3.5) 中是否有基于非哈希的 set 实现?

问:使用自定义相等比较器存储唯一 NameValuePairs 的更好方法是什么?

最佳答案

Two pairs are equal if either they have equal name or equal value

你根本无法实现 IEqualityComparer<T> 正确地符合这些标准。来自Equals的文档:

The Equals method is reflexive, symmetric, and transitive. That is, it returns true if used to compare an object with itself; true for two objects x and y if it is true for y and x; and true for two objects x and z if it is true for x and y and also true for y and z.

现在考虑配对:

x = { "A", 10 },
y = { "A", 20 },
z = { "B", 20 }

你是说xy必须相等,因为它们具有相同的名称,并且 yz必须相等,因为它们具有相同的值。这意味着(通过传递性)xz应该是相等的。

因为你无法实现 IEqualityComparer<T>正确地说,您不应该期望任何依赖于该正确性的东西都能工作。

我怀疑您会发现,如果您更详细地了解您的需求,它们要么真正需要两个集合(一个按名称,一个按值)> 从传递性的角度来看,它们没有意义。

例如,假设您有一个具有您建议的特征的集合,然后添加上面的三个元素。如果您按照 { x, y, z } 的顺序添加它们,您最终会得到一个条目。如果你按照 { z, x, y } 的顺序添加它们,你最终会得到两个。这是一个有用的集合吗?

关于c# - 非基于哈希的集合集合,用于使用自定义相等比较器存储唯一对象 - C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15474710/

相关文章:

c++ - std::set 没有前后成员函数是否有设计原因?

javascript - 创建一系列独特的组合

c# - 使用 C# 泛型进行扩展?

c# - 在 Swagger UI 中显示 HTTP 请求持续时间

c# - C++ 中的 Vector2 等效吗?

python - 当 header 不在文件开头时是否可以使用 ConfigParser?

c# - 是否可以在 tfs 2010 构建过程模板中复制文件?

grails - 如何在Grails中一次保存所有收藏

c# - 使用 linq 将集合中的项目合并在一起

c++ - 一个测试项如何在无序序列 (C++) 中进行成员资格测试?