Если рутина может выполнить свой контракт, вернувшись нормально, она должна это сделать.Если подпрограмма не может нормально вернуться без нарушения контракта, она должна выдать исключение.Если договор рутины воспринимается как данность, на самом деле не так много места для суждения при принятии решения о том, должна ли рутина вызывать исключение.Он должен возвращаться или выбрасываться на основе вышеприведенного простого правила.
Решение о месте, которое входит в уравнение, заключается в принятии решения о том, каким должен быть контракт подпрограммы.Полезным шаблоном является предоставление как версии «Try» подпрограммы, так и версии «Do»;если «пробная» версия не может выполнить запрошенное действие из-за разумно ожидаемой проблемы, это укажет это, возвращая некоторый тип значения ошибки;если версия «Do» не может выполнить запрошенное действие по какой-либо причине, она выдаст исключение.
В качестве простого примера рассмотрим «Integer.TryParse» и «Integer.Parse».Если у вас есть строка, которая может быть или не быть действительным числом, можно вызвать Integer.TryParse.Integer.TryParse будет использовать возвращенный флаг, чтобы указать, был ли анализ успешным;он будет очень счастливо возвращаться независимо от того, был ли анализ успешным или нет, и вызывающая сторона несет ответственность за обеспечение успешного выполнения TryParse перед попыткой использования возвращенного значения.Напротив, Integer.Parse будет возвращаться, только если число было успешно проанализировано.Если число неверно, Integer.Parse сгенерирует исключение.Таким образом, вызывающий код может использовать значение, возвращаемое Integer.Parse, без необходимости проверки его успешности;если Integer.Parse не удалось, он не вернулся бы.Обратите внимание, что Integer.TryParse может генерировать исключения в некоторых действительно исключительных случаях (например, если небезопасный код сделал переданную ссылку String для какого-либо другого типа объекта);единственная гарантия состоит в том, что он не будет генерировать в разумно ожидаемых случаях (например, передается строка типа «XYZ» вместо строки типа «123»).
Небольшое улучшение шаблона Try / Doчтобы подпрограмма принимала делегата, который будет вызван, если что-то пойдет не так.Во многих случаях прохождение делегата было бы излишним, и зачастую трудно заранее решить, какие параметры должен принимать делегат, но этот подход может быть полезен в тех случаях, когда решение о том, следует ли вмешиваться или отказываться от него, может быть определено извнефакторы.Такие ситуации возникают в сценариях связи, где правильным ответом программы на сбой связи может быть сообщение, уведомляющее пользователя о том, что программа испытывает затруднения, и позволяющее пользователю нажать «отмена», но программа должна повторить операцию.несколько раз, если пользователь не делает.Если операция, которую нужно было повторить, составляла небольшую часть общей операции, которую нужно выполнить, выброс исключения в основную строку «окончательно» прекратил бы более крупную операцию, в то время как выполнение попыток без взаимодействия с пользователем может заставить пользователясидеть долго и досадно, пока компьютер не откажется от операции, которую пользователь может знать, что это не удастся (например, из-за того, что батарея просто разрядилась на устройстве, с которым он связывался).Использование делегата обратного вызова обеспечивает оптимальное взаимодействие с пользовательским интерфейсом без привязки кода связи к какой-либо конкретной реализации пользовательского интерфейса.