当尝试向集合中添加重复项时,应该抛出什么异常类型?

38

以下代码应该抛出异常,以防止添加重复的集合项。

ICollection<T> collection = new List<T>();

public void Add(T item)
{
    if (collection.Contain(item))
    {
          throw new SomeExceptionType()
    }

    collection.Add(item);
}

什么标准异常类型最合适?

3
我找到的最接近的特定异常是DuplicateNameException,针对数据库...但这对于“Collection”来说只是个坏主意。带回家的信息是:任何想要更具体的人都可以自己编写异常。 - KCD
8个回答

48

好的,Dictionary<,>.Add()会在存在重复键时抛出ArgumentException异常,所以我想这可能是一个先例。


12

Linq使用两个新的异常DuplicateNameExceptionDuplicateKeyException,如果你正在使用system.data程序集,则可以使用它们。


6

ArgumentException可能是最好的选择。当参数无效时,会抛出此异常。


4
我会使用InvalidOperationException

当方法调用对于对象的当前状态无效时引发的异常。

由于参数值的有效性取决于对象的状态(即是否为true的collection.Contains(item)),因此我认为这是最好的异常处理方式。
确保您为异常添加良好的消息,使调用者清楚地了解问题所在。

2
在我看来,InvalidOperationException 会让用户感到困惑,因为它通常用于显示不适当的操作序列。例如,从已关闭的读取器中读取等。 - klashar

3

参数异常是正确的异常(字典也使用该异常)


2
我认为应该是 InvalidOperationException,因为添加已经存在于集合中的对象是无效的。

如果它是一个字典,那么这个说法是正确的,但事实上并不是。 - Brandon
1
有些集合不允许重复,而有些字典允许它们存在...在发帖者的情况下,他显然不想要重复项,否则为什么要抛出异常呢? - Thomas Levesque
抱歉,我那条评论用词不当,我的意思更多的是说,如果 OP 使用的集合允许重复,那么这并不算是一项无效操作。这只是一个“他不认为这是有效的”问题。此外,我不是给这个人点踩的人 >_> 我不认为这是最好的例外情况,但我认为使用它也不会有错。 - Brandon

1
System.ArgumentException

1

我会抛出一个 ArgumentException。这就是泛型 System.Collections.Generic.SortedList<> 在其 Add 方法中所做的。

来自 .NET Framework 2.0 代码:

    public void Add(TKey key, TValue value)
    {
        if (key == null)
        {
            System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.key);
        }
        int num = Array.BinarySearch<TKey>(this.keys, 0, this._size, key, this.comparer);
        if (num >= 0)
        {
            System.ThrowHelper.ThrowArgumentException(System.ExceptionResource.Argument_AddingDuplicate);
        }
        this.Insert(~num, key, value);
    }

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