2011-03-01 57 views
71

在C#中是否有一個集合不會讓您向其中添加重複的項目?例如,傻類的僅允許.NET中唯一項目的集合?

public class Customer { 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string Address { get; set; } 

    public override int GetHashCode() { 
     return (FirstName + LastName + Address).GetHashCode(); 
    } 

    public override bool Equals(object obj) { 
     Customer C = obj as Customer; 
     return C != null && String.Equals(this.FirstName, C.FirstName) && String.Equals(this.LastName, C.LastName) && String.Equals(this.Address, C.Address); 
    } 
} 

將下面的代碼(顯然)拋出一個異常:

Customer Adam = new Customer { Address = "A", FirstName = "Adam", LastName = "" }; 
Customer AdamDup = new Customer { Address = "A", FirstName = "Adam", LastName = "" }; 

Dictionary<Customer, bool> CustomerHash = new Dictionary<Customer, bool>(); 
CustomerHash.Add(Adam, true); 
CustomerHash.Add(AdamDup, true); 

但是有沒有將同樣保證唯一性一類,但沒有KeyValuePairs?我認爲HashSet<T>會這樣做,但閱讀文檔看來,類只是一個集合實現(去圖)。

+3

我不明白你的問題'HashSet '。 MSDN說:「HashSet 類提供了高性能的集合操作,一個集合是一個不包含重複元素的集合,其元素沒有特定的順序。」 – 2011-03-01 17:11:20

+4

你能解釋一下爲什麼'HashSet '不夠? – JaredPar 2011-03-01 17:11:46

+0

@ mootinator:'Dictionary 'class *不保證任何順序。 – LukeH 2011-03-01 17:23:15

回答

147

HashSet<T>是你在找什麼。從MSDN(強調增加):

HashSet<T>類提供了高性能的集合操作。一組是不包含重複元素,並且其元素沒有特定順序的集合。

注意,HashSet<T>.Add(T item) method返回bool - 如果該項目被添加到集合true;如果該項目已經存在,則爲false

10

HashSet<T>頁面上MSDN:

HashSet中(Of T)類提供高性能的設置操作。 一個集合是一個不包含重複元素的集合,其元素沒有特定的順序。

(重點煤礦)

4

您可以嘗試HashSet<T>

+2

http://meta.stackoverflow.com/tags/link-only-answers/info – 2013-12-05 00:13:31

3

如果您所需要的只是確保元素的唯一性,那麼HashSet就是您所需要的。

當你說「只是一套實施」時,你是什麼意思?一個集合(根據定義)是不保存元素順序的唯一元素的集合。

+0

你完全正確;這個問題有點愚蠢。基本上,我一直在尋找添加副本時會引發異常的東西(如Dictionary ),但如前所述,HashSet 在重複添加時返回false。 +1,謝謝。 – 2011-03-01 18:59:50

1

我想補充我的2美分...

如果你需要一個ValueExistingException投擲HashSet<T>,你還可以創建你的收藏很容易:

public class ThrowingHashSet<T> : ICollection<T> 
{ 
    private HashSet<T> innerHash = new HashSet<T>(); 

    public void Add(T item) 
    { 
     if (!innerHash.Add(item)) 
      throw new ValueExistingException(); 
    } 

    public void Clear() 
    { 
     innerHash.Clear(); 
    } 

    public bool Contains(T item) 
    { 
     return innerHash.Contains(item); 
    } 

    public void CopyTo(T[] array, int arrayIndex) 
    { 
     innerHash.CopyTo(array, arrayIndex); 
    } 

    public int Count 
    { 
     get { return innerHash.Count; } 
    } 

    public bool IsReadOnly 
    { 
     get { return false; } 
    } 

    public bool Remove(T item) 
    { 
     return innerHash.Remove(item); 
    } 

    public IEnumerator<T> GetEnumerator() 
    { 
     return innerHash.GetEnumerator(); 
    } 

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 
     return this.GetEnumerator(); 
    } 
} 

例如,這可以是有用的,如果你需要它在很多地方......

+0

當然。我想知道是否有內置任何東西,但謝謝+1 – 2011-03-01 19:05:37

16

如何在HashSet上擴展方法?

public static void AddOrThrow<T>(this HashSet<T> hash, T item) 
{ 
    if (!hash.Add(item)) 
     throw new ValueExistingException(); 
} 
相關問題