Когда вы пишете классы / функции для использования другими, кажется, что трудно сказать, когда уместны исключения. Есть некоторые полезные части BCL, которые мне пришлось бросить и пойти на пинвоук, потому что они выдают исключения, а не возвращают ошибки. В некоторых случаях вы можете обойти это, но в других, таких как System.Management и Performance Counter, есть случаи, когда вам нужно делать циклы, в которых BCL часто генерирует исключения.
Если вы пишете библиотеку, и существует отдаленная вероятность того, что ваша функция может использоваться в цикле, и существует вероятность большого количества итераций, используйте шаблон Try .. или какой-либо другой способ показать ошибки помимо исключений. И даже тогда трудно сказать, сколько будет вызываться ваша функция, если она используется многими процессами в общей среде.
В моем собственном коде исключения генерируются только тогда, когда вещи настолько исключительны, что необходимо пойти посмотреть на трассировку стека и посмотреть, что пошло не так, а затем исправить это. Поэтому я в значительной степени переписал части BCL, чтобы использовать обработку ошибок на основе шаблона Try .. вместо исключений.