Правильное использование 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 are ArgumentNullException и ArgumentOutOfRangeException. Эти производные классы должны использоваться вместо ArgumentException, за исключением ситуаций, когда ни один из производных классов не является приемлемым.

для второго примера, то тут должен ли я бросить KeyNotFoundException для поиск по базе данных? они предлагают (в комментариях)

if (user == null) throw new ObjectNotFoundException();

определена в System.Data: System.Data.ObjectNotFoundException.