重新抛出包装对象的异常

Şaf*_*Gür 3 .net c# exception-handling exception try-catch

ConcurrentDictionary<TKey, TValue>用来实现一个ConcurrentSet<T>.

public class ConcurrentSet<T> : ISet<T>
{
    private readonly ConcurrentDictionary<T, byte> collection;
}
Run Code Online (Sandbox Code Playgroud)

ConcurrentDictionary<TKey, TValue> 不能包含具有null键的对.

// summary, param, returns...
/// <exception cref="ArgumentNullException">
///     <paramref name="item" /> is null.
/// </exception>
public bool Add(T item)
{
    // This throws an argument null exception if item is null.
    return this.collection.TryAdd(item, 0);
}
Run Code Online (Sandbox Code Playgroud)

所以,我应该

if (item == null)
    throw new ArgumentNullException("item", "Item must not be null.");

return this.collection.TryAdd(item, 0);
Run Code Online (Sandbox Code Playgroud)

或者,我应该,

try
{
    return this.collection.TryAdd(item, 0);
}
catch (ArgumentNullException)
{
    throw new ArgumentNullException("item", "Item must not be null.");
}
Run Code Online (Sandbox Code Playgroud)

或者,我应该,

try
{
    return this.collection.TryAdd(item, 0);
}
catch (ArgumentNullException x)
{
    // I know, but I don't want to preserve the stack trace
    // back to the underlying dictionary, anyway.
    throw x;
}
Run Code Online (Sandbox Code Playgroud)

或者,我应该,

try
{
    return this.collection.TryAdd(item, 0);
}
catch (ArgumentNullException)
{
    // The thrown exception will have "key", instead of
    // "item" as the parameter's name, in this instance.
    throw;
}
Run Code Online (Sandbox Code Playgroud)

这样做的正确方法是什么?

cad*_*ll0 7

我会选择这个

public bool Add(T item)
{
    // This throws an argument null exception if item is null.
    return this.collection.TryAdd(item, 0);
}
Run Code Online (Sandbox Code Playgroud)

或这个

if (item == null)
    throw new ArgumentNullException("item", "Item must not be null.");

return this.collection.TryAdd(item, 0);
Run Code Online (Sandbox Code Playgroud)

这取决于你的班级是否关心是否有空.

如果您执行空检查的唯一原因是避免将null传递给TryAdd,则不要打扰检查. TryAdd将自己检查并抛出异常.

如果在某些时候您认为您可能使用允许null的其他集合,但您仍希望您的集合不具有空值,那么您应该检查自己.如果在未来某个时间点发生变化,这将保护您.

参数的验证应该始终是方法的第一步.如果参数无效,则无需做任何其他事情.

如果要对它进行某些操作,则应该只捕获异常.如果您只是要重新抛出,或者创建一个等效的新表达式,那么就不要去抓它了.