从我所看到的情况来看,ArgumentExceptions
通常是这样使用的:
public void UpdateUser(User user)
{
if (user == null) throw new ArgumentException("user");
// etc...
}
但如果我有这样的话怎么办:
public void UpdateUser(int idOfUser)
{
var user = GetUserById(idOfUser);
if (user == null) throw new ArgumentException("idOfUser");
// etc...
}
那还是ArgumentException
吗?
答案 0 :(得分:5)
第一个
if (user == null) throw new ArgumentException("user");
应该是
if (user == null) throw new ArgumentNullException("user");
如果可能,你不应该直接抛出ArgumentException
ArgumentException
的主要派生类是ArgumentNullException
和ArgumentOutOfRangeException
。应该使用这些派生类而不是ArgumentException
,除非在两个派生类都不可接受的情况下。
对于第二个例子,这里Should I throw a KeyNotFoundException for a database lookup?他们建议(在评论中)
if (user == null) throw new ObjectNotFoundException();
它在System.Data
:System.Data.ObjectNotFoundException
中定义。
答案 1 :(得分:0)
顾名思义,ArgumentException
是一个关于参数的例外。这意味着论证本质上是错误的。
一般形式是:
public void SomeMethod(SomeType arg)
{
if(!TestArgValid(arg))
throw new ArgumentException("arg"); //Or more specific is possible
//e.g. ArgumentNullException
/* Actually do stuff */
}
如果 GetUserById
可能失败的唯一可能的方式是idOfUser
的值本身存在错误,那么以下将会两者在实践中都是一样的:
public void UpdateUser(int idOfUser)
{
if(!TestValid(idOfUser))
throw new ArgumentException("idOfUser");
var user = GetUserById(idOfUser);
// Do stuff with user
}
public void UpdateUser(int idOfUser)
{
var user = GetUserById(idOfUser);
if(user == null)
throw new ArgumentException("idOfUser");
// Do stuff with user
}
并且如果结果出于某种原因更快或更少浪费某些资源来测试user
之后的事件而不是事件之前的idOfUser
和如果没有调用GetUserById
的副作用,如果差异实际重要,那么可能第二个版本将是合理的优化第一个。
但只有在上面的所有 if 成立时才会成立,这就是检测无效参数的一种奇怪方式,这种参数具有一些特定优势,我们可以通过隐藏方法来封装方法来自其他一切的奇怪。
可能有一个有效的idOfUser
可能没有相应的user
,在这种情况下它肯定不是一个参数例外。