只允许.NET中的唯一项目的集合?

时间:2011-03-01 17:08:01

标签: c# set hashset

C#中是否有一个集合不允许您向其添加重复项目?例如,愚蠢的

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>会这样做,但是在阅读了文档后,似乎该类只是一个集合实现( go figure )。

7 个答案:

答案 0 :(得分:181)

HashSet<T>正是您正在寻找的。来自MSDN(强调补充):

  

HashSet<T>类提供高性能的集合操作。集合是不包含重复元素的集合,其元素没有特定的顺序。

请注意,如果项目已添加到集合中,则HashSet<T>.Add(T item) method会返回bool - true; false如果该项目已经存在。

答案 1 :(得分:18)

如何只在HashSet上使用扩展方法?

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

答案 2 :(得分:11)

来自MSDN上的HashSet<T>页:

  

HashSet(Of T)类提供高性能的集合操作。 集合是一个不包含重复元素的集合,其元素没有特定的顺序。

(强调我的)

答案 3 :(得分:4)

您可以尝试HashSet<T>

答案 4 :(得分:3)

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

当你说“只是一套实施”时,你是什么意思?一个集合(根据定义)是一个不保存元素顺序的唯一元素的集合。

答案 5 :(得分:2)

加上我的2美分......

如果你需要一个ValueExistingException-throwing 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();
    }
}

如果您在很多地方需要它,这可能很有用......

答案 6 :(得分:0)

您可能会按照以下方式查看唯一列表

public class UniqueList<T>
{
    public List<T> List
    {
        get;
        private set;
    }
    List<T> _internalList;

    public static UniqueList<T> NewList
    {
        get
        {
            return new UniqueList<T>();
        }
    }

    private UniqueList()
    {            
        _internalList = new List<T>();
        List = new List<T>();
    }

    public void Add(T value)
    {
        List.Clear();
        _internalList.Add(value);
        List.AddRange(_internalList.Distinct());
        //return List;
    }

    public void Add(params T[] values)
    {
        List.Clear();
        _internalList.AddRange(values);
        List.AddRange(_internalList.Distinct());
       // return List;
    }

    public bool Has(T value)
    {
        return List.Contains(value);
    }
}

您可以按照以下方式使用它

var uniquelist = UniqueList<string>.NewList;
uniquelist.Add("abc","def","ghi","jkl","mno");
uniquelist.Add("abc","jkl");
var _myList = uniquelist.List;

即使添加重复项,也只会始终返回"abc","def","ghi","jkl","mno"