Чтение статьи об исключениях Эрика Липперта определенно открыло мне глаза на то, как мне следует подходить к исключениям как в качестве производителя, так и потребителя. Тем не менее, я все еще изо всех сил пытаюсь определить руководство относительно того, как избежать создания неприятных исключений.
В частности:
- Предположим, у вас есть метод Save, который может потерпеть неудачу, потому что a) Кто-то еще изменил запись перед вами , или b) Значение, которое вы пытаетесь создать, уже существует . Эти условия должны быть ожидаемыми и не исключительными, поэтому вместо создания исключения вы решаете создать Try-версию вашего метода TrySave, который возвращает логическое значение, указывающее, успешно ли выполнено сохранение. Но если это не поможет, как потребитель узнает, в чем проблема? Или было бы лучше вернуть перечисление с указанием результата, вроде Ok / RecordAlreadyModified / ValueAlreadyExists? С integer.TryParse эта проблема не существует, так как есть только одна причина, по которой метод может завершиться ошибкой.
- Действительно ли предыдущий пример является неприятной ситуацией? Или выбрасывание исключения в этом случае будет предпочтительным способом? Я знаю, как это делается в большинстве библиотек и сред, включая платформу Entity.
- Как вы решаете, когда создавать версию Try вашего метода, а не предоставлять какой-либо способ заранее проверить, будет ли метод работать или нет? В настоящее время я следую этим рекомендациям:
- Если есть вероятность возникновения гонки, создайте пробную версию. Это предотвращает необходимость для потребителя поймать экзогенное исключение. Например, в методе Save, описанном ранее.
- Если метод для проверки условия в значительной степени будет делать все то же, что и оригинальный метод, то создайте версию Try. Например, integer.TryParse ().
- В любом другом случае создайте метод для проверки условия.