Collection that allows only unique items in .NET?

2019-01-22 05:16发布

Is there a collection in C# that will not let you add duplicate items to it? For example, with the silly class of

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);
    }
}

The following code will (obviously) throw an exception:

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);

But is there a class that will similarly guarantee uniqueness, but without KeyValuePairs? I thought HashSet<T> would do that, but having read the docs it seems that class is just a set implementation (go figure).

标签: c# set hashset
6条回答
对你真心纯属浪费
2楼-- · 2019-01-22 05:28

You can try HashSet<T>

查看更多
祖国的老花朵
3楼-- · 2019-01-22 05:48

If all you need is to ensure uniqueness of elements, then HashSet is what you need.

What do you mean when you say "just a set implementation"? A set is (by definition) a collection of unique elements that doesn't save element order.

查看更多
走好不送
4楼-- · 2019-01-22 05:50

From the HashSet<T> page on MSDN:

The HashSet(Of T) class provides high-performance set operations. A set is a collection that contains no duplicate elements, and whose elements are in no particular order.

(emphasis mine)

查看更多
干净又极端
5楼-- · 2019-01-22 05:51

HashSet<T> is what you're looking for. From MSDN (emphasis added):

The HashSet<T> class provides high-performance set operations. A set is a collection that contains no duplicate elements, and whose elements are in no particular order.

Note that the HashSet<T>.Add(T item) method returns a bool -- true if the item was added to the collection; false if the item was already present.

查看更多
放荡不羁爱自由
6楼-- · 2019-01-22 05:51

How about just an extension method on HashSet?

public static void AddOrThrow<T>(this HashSet<T> hash, T item)
{
    if (!hash.Add(item))
        throw new ValueExistingException();
}
查看更多
爱情/是我丢掉的垃圾
7楼-- · 2019-01-22 05:54

Just to add my 2 cents...

if you need a ValueExistingException-throwing HashSet<T> you can also create your collection easily:

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();
    }
}

this can be useful for example if you need it in many places...

查看更多
登录 后发表回答