【问题标题】:ExceptWith in HashSet for complex types复杂类型的 HashSet 中的 exceptWith
【发布时间】:2013-03-05 06:01:14
【问题描述】:

我有自定义类的 HashSet:

public class Vertex
{
    public string Name;

    public override bool Equals(object obj)
    {
        var vert = obj as Vertex;
        if (vert !=null)
        {
            return Name.Equals(vert.Name, StringComparison.InvariantCulture);
        }
        return false;
    }
}

现在我有两个哈希集

HashSet<Vertex> hashSet1 = new HashSet<Vertex>();

HashSet<Vertex> hashSet1 = new HashSet<Vertex>();

现在我想在 hashSet1 中只包含不在 hashSet2 中的顶点 所以我使用了ExceptWith方法

hashSet1.ExceptWith(hashSet2);

但这不起作用。 我想这不起作用,因为我有复杂的类型。 所以问题是:是否需要在 Vertex 类中实现一些接口才能使这个东西工作? 我知道在创建 HashSet 时我可以传递一个 EqualityComparer 但在我看来,在 Vertex 类中实现一些比较接口方法会更优雅。

有可能还是我只是不明白某事?

谢谢。

【问题讨论】:

标签: c# equals hashset


【解决方案1】:

当覆盖Equals 时,您还应该覆盖GetHashCodeHashSet(以及其他像 Dictionary 这样的散列结构)将首先为您的对象计算一个散列码,以便在将元素与 Equals 进行比较之前将它们定位在结构中。

public override int GetHashCode()
{
    return StringComparer.InvariantCulture.GetHashCode(this.Name);
}

【讨论】:

    【解决方案2】:

    鼓励您不必实现任何接口(尽管IEquatable&lt;T&gt;)。当您在未指定相等比较器的情况下创建哈希集时,它默认使用EqualityComparer&lt;T&gt;.Default,它要求对象本身相互比较(特殊情况下的空引用)。

    但是,在您的情况下,您的平等合同已被破坏,因为您尚未覆盖 GetHashCode。以下是我将如何修正您的类型:

    public class Vertex : IEquatable<Vertex>
    {
        public string Name { get; private set; }
    
        public Vertex(string name)
        {
            Name = name;
        }
    
        public override int GetHashCode()
        {
            return StringComparer.InvariantCulture.GetHashCode(Name);
        }
    
        public override bool Equals(object obj)
        {
            return Equals(obj as Vertex);
        }
    
        public bool Equals(Vertex obj)
        {
            return obj != null && StringComparer.InvariantCulture.Equals(Name, obj.Name);
        }
    }
    

    【讨论】:

      【解决方案3】:

      您介意覆盖.GetHashCode()too 吗?

      这是reference

      【讨论】:

        【解决方案4】:

        你必须用Equals覆盖GetHashCode

        Object.Equals Method:

        覆盖 Equals(Object) 的类型也必须覆盖 GetHashCode;否则,哈希表可能无法正常工作。

        【讨论】:

          猜你喜欢
          • 2020-06-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-04-19
          • 1970-01-01
          • 2020-03-04
          相关资源
          最近更新 更多