Исправить исключение для пустой строки \null, переданной конструктору

У меня есть класс:

class Foo
{
    public Foo(string bar)
    {
        if (string.IsNullOrEmpty(bar))
            throw new Exception("bar must not be null or empty.");
    }
}

Каков самый правильный тип исключения для броска?

К жизнеспособным кандидатам относятся:

  • ArgumentNullException
  • ArgumentException
  • InvalidOperationException
  • TypeInitializationException (не в соответствии с dasblinkenlight ниже)

Мой инстинкт состоит в том, чтобы пойти с InvalidOperationException, поскольку вызывающий пытается создать объект в незаконном состоянии, хотя ArgumentException имеет также достоинства.

Мне жаль, что не было StringNullOrEmptyException, разве это не здорово?

Edit Спасибо за предложенный вопрос, это похоже, но я спрашивал конкретно об этом, происходящем в конструкторе, и может ли это вообще изменить рекомендацию.

Ответ 1

Я предполагаю, что наиболее правильная реализация будет следующей:

if (bar == null) { throw new ArgumentNullException (...); }
else if (bar.Trim() == "") { throw new ArgumentException (...); }

но мы могли бы напрячь комара и усвоить верблюда. Это, вероятно, не очень важно.

С другой стороны, вы можете создать класс StringNullOrEmptyException.

Ответ 2

Один очень распространенный способ обращения с подобными ситуациями - это бросить два разных исключения: один для null и еще один для недопустимой ненулевой строки:

if (bar == null) {
    throw new ArgumentNullException("bar");
}
if (string.IsNullOrWhiteSpace(bar)) {
    throw new ArgumentException("bar");
}

Поскольку вы упомянули другие исключения, вот что они означают:

  • ArgumentNullException - указывает, что данный аргумент null
  • ArgumentException - указывает, что аргумент не является нулевым, но в противном случае он недействителен.
  • InvalidOperationException - указывает, что операция не может быть выполнена в текущем состоянии объекта.
  • TypeInitializationException - указывает, что тип (а не экземпляр типа, но сам тип) не может быть инициализирован.

Первые три исключения из этого списка всегда указывают на проблему программирования на стороне вызывающего абонента, то есть получатели, получающие их, знают, что они должны исправить свой код, потому что они неправильно вызывают ваш API.

Последнее исключение указывает на проблему программирования на вашей стороне, то есть вызывающие пользователи, получающие эту ошибку, знают, что они должны позвонить вам, чтобы исправить вашу ошибку, или перенастроить способ, которым они установили вашу библиотеку.

Ответ 3

ArgumentException имеет наибольший смысл здесь по следующим причинам.

  • ArgumentNullException → недействителен, потому что строка может быть пустой.
  • InvalidOperationException → это не операция, которая терпит неудачу, это аргумент в конструкторе

Если вы действительно хотите StringNullOrEmptyException, вы можете создать его самостоятельно, но большинство склоняется к тому, что нужно придерживаться определенных Исключением системы.