Правильное использование ArgumentException?
из того, что я видел, 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
?
2 ответов
как следует из названия, an ArgumentException
исключение о аргумент. Это означает, что аргумент был каким-то образом изначально неправильным.
в общем виде:
public void SomeMethod(SomeType arg)
{
if(!TestArgValid(arg))
throw new ArgumentException("arg"); //Or more specific is possible
//e.g. ArgumentNullException
/* Actually do stuff */
}
если the только возможно 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
и если разница действительно имела значение тогда может быть вторая версия была бы разумной оптимизацией первой.
но это только в том случае, если все еслиs выше hold, и это странный способ обнаружения недопустимого аргумента, который имеет какое-то конкретное преимущество, когда мы выигрываем от инкапсуляции методов, скрывая эту странность от всего остального.
скорее всего, может быть действительный idOfUser
для которого не было соответствующего user
, в этом случае это, конечно, не было исключением аргумента.
первый
if (user == null) throw new ArgumentException("user");
должно быть
if (user == null) throw new ArgumentNullException("user");
если возможно, вы не должны бросать ArgumentException
напрямую
первичные производные классы
ArgumentException
areArgumentNullException
иArgumentOutOfRangeException
. Эти производные классы должны использоваться вместоArgumentException
, за исключением ситуаций, когда ни один из производных классов не является приемлемым.
для второго примера, то тут должен ли я бросить KeyNotFoundException для поиск по базе данных? они предлагают (в комментариях)
if (user == null) throw new ObjectNotFoundException();
определена в System.Data
: System.Data.ObjectNotFoundException
.