2011-03-01 48 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(); 
}