从我所看到的,ArgumentExceptions
通常使用如下:
public void UpdateUser(User user)
{
if (user == null) throw new ArgumentException("user");
// etc...
}
Run Code Online (Sandbox Code Playgroud)
但如果我有这样的事情怎么办:
public void UpdateUser(int idOfUser)
{
var user = GetUserById(idOfUser);
if (user == null) throw new ArgumentException("idOfUser");
// etc...
}
Run Code Online (Sandbox Code Playgroud)
那还是ArgumentException
吗?
首先
if (user == null) throw new ArgumentException("user");
Run Code Online (Sandbox Code Playgroud)
应该
if (user == null) throw new ArgumentNullException("user");
Run Code Online (Sandbox Code Playgroud)
如果可能的话,你不应该ArgumentException
直接投掷
主要派生类
ArgumentException
是ArgumentNullException
和ArgumentOutOfRangeException
.应该使用这些派生类来代替ArgumentException
,除非在两个派生类都不可接受的情况下.
对于第二个示例,这里我应该为数据库查找抛出KeyNotFoundException吗?他们建议(在评论中)
if (user == null) throw new ObjectNotFoundException();
Run Code Online (Sandbox Code Playgroud)
它的定义System.Data
如下:System.Data.ObjectNotFoundException
.
顾名思义,anArgumentException
是参数的例外。这意味着这个论点在某种程度上本质上是错误的。
一般形式为:
public void SomeMethod(SomeType arg)
{
if(!TestArgValid(arg))
throw new ArgumentException("arg"); //Or more specific is possible
//e.g. ArgumentNullException
/* Actually do stuff */
}
Run Code Online (Sandbox Code Playgroud)
如果唯一可能失败的方式是 的值存在本质上的错误,那么以下内容在实践中都是相同的: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
}
Run Code Online (Sandbox Code Playgroud)
如果由于某种原因事实证明user
事后测试比idOfUser
事前测试更快或更少浪费一些资源,并且如果调用没有副作用GetUserById
,并且如果差异实际上很重要,那么第二个版本可能会是首先合理优化。
但是,只有当上面的所有if都成立时,这种情况才成立,这是一种检测无效参数的奇怪方法,它具有一些特定的优势,通过将这种奇怪的东西隐藏在其他事物中,我们可以从方法的封装中受益。
有可能存在一个idOfUser
没有对应的valid user
,在这种情况下它肯定不是一个参数异常。