2013-03-16 14 views
4

我有我的自定义类的HashSet的:ExceptWith在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; 
    } 
} 

现在我有拖hashsets

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

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

现在我想在hashSet1只有顶点是未在hashSet2 于是我就用ExceptWith方法

hashSet1.ExceptWith(hashSet2); 

但是,这是行不通的。 我想这是行不通的,因为我有复杂的类型。 所以问题是:是否有一些需要在Vertex类中实现的接口来使这件事情起作用? 我知道虽然创建HashSet I可以传递EqualityComparer,但在我看来,在Vertex类中实现一些比较接口方法会更优雅。

有可能或者我只是不明白......吗?

谢谢。

+0

http://msdn.microsoft.com/en-us/library/ms173147%28v=vs.80%29.aspx – 2013-03-16 15:01:16

回答

4

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

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

,这是简单的)谢谢 – steavy 2013-03-16 15:03:18

1

你也介意重写.GetHashCode()吗?

这是reference

0

您必须覆盖GetHashCode并覆盖Equals

Object.Equals Method:即重写equals(对象)也必须重写GetHashCode

类型;否则,哈希表可能无法正常工作。

2

您不必实现任何接口(尽管IEquatable<T>)被鼓励。当你创建一个没有指定等值比较器的散列集时,它默认使用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); 
    } 
}