Мне кажется, я знаю, что имею в виду, но не совсем уверен ...
Документация Framework описывает тип следующим образом:
Исключение, которое выдается, когда вызов метода недопустим для текущего состояния объекта.
Существуют явные случаи, и на ум приходит случай, когда для операции требуется открытая база данных, но объект не был инициализирован с необходимой информацией для подключения к базе данных.
(Касательно: ADO.NET, с другой стороны, требует, чтобы вы явно открывали соединение, с другой стороны, не так однозначно; DataAdapter отклоняется от этого, просто открывая соединение instad, закрывая его снова тогда и только тогда, когда оно был закрыт при входе, и я нахожу это удобным и сделал себе оболочку ADO.NET, которая использует этот шаблон для всего. Конечно, это означает, что я рискую сделать 2 ExecuteNonQuery и без необходимости возвращать промежуточное соединение с пулом, но я все еще могу открывать и закрывать соединение, когда я хочу, и это снижение производительности ничто по сравнению с получением исключения.)
Полагаю, ответ на мой вопрос заключается в том, что ТОЛЬКО в таких четких ситуациях мы должны выбросить исключение. Но какой тип исключения будет наиболее подходящим в следующем сценарии:
</p>
<pre>
public class FormatterMapping
{
Dictionary formattersByName = new ...();
public IFormatter GetFormatter(string key)
{
IFormatter f;
if (formattersByName.TryGetValue(key, out f))
return f;
else
throw new ??Exception("explanation of why this failed.");
}
}
</pre>
<p>
Моим первым инстинктом было выбрасывать ArgumentException. Затем я начал думать, что с тем же успехом может быть и то, что в сопоставлении отсутствует ключ, поскольку аргумент «неправильный». По сути, операция «Получить форматтер X» недопустима , потому что X не отображается в отображении, но я не имею понятия, должен ли был там «X» или нет смысла просить X здесь.
Конечно, я мог бы обойти всю проблему, вернув ноль, но это открывает большую, более глубокую банку червей. Нет никакого способа узнать, когда будет использоваться возвращаемое значение, поэтому код, взрывающийся позже с NullReferenceException, может не иметь очевидного отношения к месту, где все пошло не так. Либо отображение было неправильно настроено, либо код, использующий его, запрашивал что-то, чего не должно быть.
Еще один способ избежать этой проблемы - использовать опцию TryGetFormatter, но способ, которым я собираюсь использовать это, на самом деле должен вызывать то, что есть, а что нет в отображении, поэтому навязывание этого шаблона пользователю код тоже не хорошо.
Пожалуйста, не отвечайте, я должен просто выбросить ApplicationException! И что бы вы ни думали о коде, укажите причины этого. Это в конце концов, что рассуждения, которые действительно здесь обсуждаются.
Пока никто не убедит меня в обратном, я склоняюсь к ArgumentException. С точки зрения отображения аргумент неверен, поэтому, по крайней мере, есть одна четкая линия аргументации, подтверждающая это. :)