当添加重复项时抛出异常的.NET集合

13

除了字典(Dictionary),.NET框架(3.5)中是否有一个集合会在添加重复项时抛出异常?

HashSet在此处不会抛出异常:

HashSet<string> strings = new HashSet<string>();
strings.Add("apple");
strings.Add("apple");

而词典则:

Dictionary<string, string> dict = new Dictionary<string, string>();
dict.Add("dude", "dude");
dict.Add("dude", "dude"); //throws exception

编辑:有没有不需要(键,值)的集合可以做到这一点?如果可能,我还想要AddRange...

我自己写了一个:

public class Uniques<T> : HashSet<T>
{

    public Uniques()
    { }

    public Uniques(IEnumerable<T> collection)
    {
        AddRange(collection);
    }

    public void Add(T item)
    {
        if (!base.Add(item))
        {
            throw new ArgumentException("Item already exists");
        }
    }


    public void AddRange(IEnumerable<T> collection)
    {
        foreach (T item in collection)
        {
            Add(item);
        }
    }
}

好的,我看到你的编辑了,我会删除我的原始答案。针对你的编辑,我的回答是不可以。 - ParmesanCodice
你不应该在“Add”方法签名中添加“new”关键字,因为它会隐藏继承成员HashSet<T>.Add(T)。 - Gerard
为什么不在HashSet<T>中添加扩展方法? 像AddRange/RemoveMany这样的方法就像Linq一样。 - Tomer W
3个回答

19

但是如果值已经存在,HashSet.Add方法会返回false - 这不已经足够了吗?

HashSet<string> set = new HashSet<string>();
...
if (!set.Add("Key"))
    /* Not added */

2
它允许您在不检查Contains的成本的情况下添加,实现两个操作一次调用。在Dictionary<,>中没有TryAdd方法。 - Guillaume
我更喜欢这种方式,但很奇怪的是,ICollection.Add返回void,而其他不允许重复项的集合会抛出异常... - Guillaume
好的,我有点想要AddRange功能。谢谢。 - geejay
哎呀...确实是这样。 - alexkovelsky

0

如果你正在寻找类似于AddRange的功能,请查看C5。C5系列中的集合在其接口中公开了更多的功能,包括一个函数AddAll,它接受一个可枚举对象,将可枚举对象中的所有项依次添加到集合中。

编辑:还要注意,C5集合实现了System.Collections.GenericICollectionIList接口(适当的情况下),因此可以作为实现甚至在期望这些接口的系统中使用。


0

补充Bjorn的回答,如果你还想要一个类似于IList.AddRange函数的功能,可以使用HashSet<T>.UnionWith来自MSDN):

HashSet(T).UnionWith方法

修改当前的HashSet对象,使其包含存在于它自身、指定集合或两者中的所有元素。

public void UnionWith(
    IEnumerable<T> other
)

唯一的问题可能是:我相当确定这需要 .NET Framework 3.5 SP1 或更高版本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接