2013-03-16 167 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); 
    } 
}