Удивительно, но я только смог найти один предыдущий вопрос о SO по этому вопросу, и я просто хотел бы получить сообщество "Голосуй за доверие" (или нет!) по моему подходу.
Таким образом, я вижу:
- используйте
Debug.Assert
, чтобы указать, что будет выглядеть EXPECT. Это будет использоваться, когда мы полностью контролируем нашу среду, например, в методе проверьте некоторые предварительные и последующие условия. - Использовать исключения при возникновении особых обстоятельств. Работа с внешними ресурсами, то есть файлами, базами данных, сетями и т.д., Не требует больших усилий. Но...
Он становится немного мутным в следующем сценарии. Обратите внимание, что это только КОНСТРУКТИВНЫЙ ПРИМЕР!
Скажем, у нас есть класс MyClass, который имеет общедоступное свойство MyMode и метод GetSomeValueForCurrentMode()
. Подумайте о MyClass как о том, что нужно было отгрузить (релиз построен) в библиотеке для использования другими разработчиками.
Мы ожидаем, что MyMode будет обновляться внешними пользователями этого класса. Теперь GetSomeValueForCurrentMode()
имеет следующую логику:
switch(MyMode)
{
case Mode.ModeA:
return val1;
case Mode.ModeB:
return val2;
default:
//Uh-uh this should never happen
}
Что я получаю здесь, так это то, что пользователь MyClass оставил его в недопустимом состоянии. Итак, что нам делать?
По умолчанию, должны ли мы Debug.Assert
или throw new InvalidOperationException
(или другие)?
Есть одна мантра, в которой говорится, что мы не должны доверять пользователям наших классов. Если мы выберем Debug.Assert и построим MyClass в качестве сборки релиза (таким образом удалив аргументы Debug), пользователь класса не получит полезную информацию, которую они оставили в недопустимом состоянии. Но это как-то противоречит другой мантре, которая говорит только об исключении, когда происходят вещи, совершенно вне вашего контроля.
Я нахожу, что я обойдусь кругами с этим - один из тех дискуссий по программированию, которые, похоже, не имеют окончательного "правильного" ответа. Так что позвольте поставить это на голосование!
Изменить: я заметил этот ответ в связанном SO-вопросе (Дизайн по контракту с использованием утверждений или исключений?):
Правило большого пальца состоит в том, что вы должны использовать утверждения, когда пытаетесь поймать свои собственные ошибки и исключения, когда пытаетесь поймать ошибки других людей. Другими словами, вы должны использовать исключения, чтобы проверить предварительные условия для общедоступных функций API и всякий раз, когда вы получаете какие-либо данные, которые являются внешними для вашей системы. Вы должны использовать утверждения для функций или данных, которые являются внутренними для вашей системы.
Для меня это имеет смысл и может сочетаться с техникой "Assert then throw", описанной ниже.
Мысли приветствуются!