Pull to refresh

Comments 11

Необходимость в типизации исключений, как мне кажется, опирается на различение сценариев их обработки. Многократно видел в проектах избыточно используемые классы исключений, которые имеют единый сценарий обработки. В текущем проекте multi-catch блок используется в единственном месте, реализует различную логику при ошибке авторизации и других типах исключений.

Использование единого реестра кастомных исключений (если они нужны) выглядит интересным решением.

Да, единый реестр исключений это не только более эффективно по производительности, но и более красиво.

Обычно я создаю статический класс Errors и помещаю туда все выбрасываемые исключения. Код, который создаёт текст исключения, закономерно переходит туда же. В результате мы получаем более чистый код в месте выбрасывания исключения.

У меня только один вопрос-просьба: в каких реальных, а не синтетических кейсах затраты на throw оказались настолько критичными, что потребовалась оптимизация? Приведите пример, пожалуйста

Пример: написание тиражируемых библиотек. Например, класс List<T> в базовой библиотеке .NET. Или, например, RavenDB.

а зачем выбрасывать исключение из статического метода, тем самым нарушая анализ точек выхода в компилятре/IDE (см. пример кода по ссылке RavenDB где return после вызова метода Throw..)? почему бы не вернуть исключение (интерфейс Throwable), а ключевое слово throw оставить на месте вызова статического метода? тем самым сделав эти методы статическими методами-фабриками для исключений.

Цель подобных трюков как раз в том, чтобы обмануть компилятор и попытаться заинлайнить метод. Вообще, все микрооптимизации не про красивый код, а про то, чтоб добиться производительности.

Однако, в данном конкретном случае я в версию инлайна верю слабо. Скорее тут это сделано для единообразия кода.

Тут смысл как раз в том, что throw генерирует кучу бойлерплейта вокруг себя, так что метод, где используется throw, уже может не получиться заинлайнить. Вынося же throw в отдельный метод, мы оставляем весь бойлерплейт внутри этого отдельного метода, а всё остальное прекрасно инлайнится.

Привет! Спасибо за интересную и познавательную статью. Всем, конечно хороши методы-хелперы выбрасывающие исключения, но у них есть один недостаток, в языке C# нельзя указать, что метод выбрасывает исключение, т.о. при использовании методов-хелперов, после них, далее по коду появляются предупреждения о например, использовании неинициализированных переменных или другие предупреждения, которых бы не было при явном использовании throw. Вопрос: а существует ли какой-нибудь атрибут в том же Решарпере, например, который будучи применен к методу-хелперу, "успокоил" бы компилятор, что бы он "думал", что этом обычный выброс исключения и генерировал бы описанные выше предупреждения?

Да, знакомая ситуация. И, увы, нет, я не знаю никаких способов это победить. Приходится ставить восклицательные знаки там, где я точно знаю, что не null.

Начиная с .Net Core 3.0 появились атрибуты DoesNotReturn и DoesNotReturnIf, правда, к сожалению, они влияют только на nullable-анализ. Так что делать return после вызова методов всё равно нужно…

Sign up to leave a comment.

Articles