我有我的自定义类的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类中实现一些比较接口方法会更优雅。
有没有可能,或者我只是不理解某事?
谢谢。
发布于 2013-03-16 15:01:14
当覆盖Equals
时,您也应该覆盖GetHashCode
。HashSet
(和其他散列结构,如Dictionary
)将首先为您的对象计算散列代码,以便在与Equals
比较元素之前在结构中定位它们。
public override int GetHashCode()
{
return StringComparer.InvariantCulture.GetHashCode(this.Name);
}
发布于 2013-03-16 15:06:55
您不必实现任何接口(尽管鼓励使用IEquatable
)。在没有指定相等比较器的情况下创建哈希集时,它默认使用EqualityComparer<T>.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);
}
}
发布于 2013-03-16 15:00:20
您是否介意也覆盖.GetHashCode()
?
这是reference。
https://stackoverflow.com/questions/15450758
复制相似问题