ArgumentException的正确用法
本文关键字:用法 ArgumentException | 更新日期: 2023-09-27 17:57:27
根据我所看到的,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
吗?
第一个
if (user == null) throw new ArgumentException("user");
应该是
if (user == null) throw new ArgumentNullException("user");
如果可能的话,你不应该直接扔ArgumentException
ArgumentException
的主要派生类是ArgumentNullException
和ArgumentOutOfRangeException
。应该使用这些派生类而不是ArgumentException
,除非这两个派生类都不可接受。
对于第二个示例,我应该为数据库查找抛出KeyNotFoundException吗?他们建议(在评论中)
if (user == null) throw new ObjectNotFoundException();
其定义见System.Data
:System.Data.ObjectNotFoundException
。
顾名思义,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
,在这种情况下,它肯定不是一个参数例外。