Когда я должен использовать метод ThrowHelper вместо того, чтобы бросить непосредственно?

Когда уместно использовать метод ThrowHelper вместо того, чтобы бросить непосредственно?

void MyMethod() {
    ...
    //throw new ArgumentNullException("paramName");
    ThrowArgumentNullException("paramName");
    ...
}
void ThrowArgumentNullException(string paramName) {
    throw new ArgumentNullException(paramName);
}

Я считал, что вызов метода ThrowHelper (метод с единственной целью выдать исключение) вместо того, чтобы бросить непосредственно должен привести к меньшему байт-коду.

Это и очевидная инкапсуляция (другой слой косвенности), могут быть серьезными основаниями не бросить непосредственно, по крайней мере, в некоторых сценариях.

Так или иначе IMO недостатки являются весьма существенными также.

  • Часть (исключительного) потока управления скрыта
  • Исключения заканчивают тем, что имели более загадочный stacktrace
  • компилятор (2.0) не распознает, что вызовы ThrowHelper являются точками выхода из метода, следовательно некоторый код - вокруг необходим.

Мой ограниченный опыт состоит в том, что часто общий замысел ухудшается.

int MyMethod(int i) {
    switch (i) {
        case 1:
            return 1;
        default:
            ThrowMyException();
    }
    return 0; // Unreachable (but needed) code
 }

Это может частично быть вопросом персонального вкуса. Так или иначе, каковы Ваши персональные инструкции об этой проблеме? Вы находите, что это - хорошая идея использовать ThrowHelpers для всех тех общих задач как проверка параметрического усилителя метода (ThrowArgumentNullException (paramName) и такой)? Я пропускаю что-то очевидное по этой проблеме?

Btw я пытаюсь не смешать эту проблему с проблемой проверки, например, метод как:

ThrowIfNameIsNullOrEmpty(name);
14
задан smv 30 December 2009 в 12:48
поделиться

5 ответов

Мой подход по умолчанию - бросать непосредственно из исключительной ветви кода.

Принцип DRY и правило 3 направляют, когда я бы обернул это в метод: если я обнаруживаю, что пишу один и тот же код 'throw' 3 или более раз, я рассматриваю возможность обернуть его в метод-помощник.

Однако, вместо метода throw, гораздо лучше написать фабричный метод, который создает желаемое Исключение, а затем выбросить его из исходного места:

public void DoStuff(string stuff)
{
    // Do something

    throw this.CreateException("Boo hiss!");
}

private MyException CreateException(string message)
{
    return new MyException(message);
}

Это сохраняет след стека.

.
16
ответ дан 1 December 2019 в 09:01
поделиться

Мне кажется, что это ненужная абстракция. У вас есть метод, который делает одно, названный так же многословно, как и то, что он делает.

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

В основном абстрагирование таких мелких вещей, как это, обычно возвращается, чтобы укусить вас. (Некоторое увлекательное чтение на эту тему: http://www.joelonsoftware.com/articles/LeakyAbstractions.html)

8
ответ дан 1 December 2019 в 09:01
поделиться

Я бы сказал, что единственное разумное время для этого - в чем-то вроде BCL, где количество использования класса достаточно велико, чтобы экономия могла быть того стоить. Однако это должно иметь смысл. В вашем случае, я не думаю, что вы действительно экономите место. Примеры ThrowHelper в BCL уменьшают размер, заменяя перечисления на строки и вызовы методов (для получения строковых сообщений). В вашем случае просто передаются одни и те же аргументы и, таким образом, экономия не достигается. Вызов метода стоит столько же, сколько и бросание исключения на место.

.
4
ответ дан 1 December 2019 в 09:01
поделиться

Я всегда стараюсь бросать свои собственные исключения только с целью настройки. Я могу бросить сообщение, которое вкратце расскажет мне, в чем проблема (и, возможно, откуда она взялась). Что касается проблем с производительностью, я стараюсь максимально ограничить количество исключений, бросаемых на release версиях моих программ, так что на самом деле я никогда не задумывался об этом слишком много. Мне интересно посмотреть, что скажут другие.

Это мои 2 цента. Пожалуйста, примите это как должное

.
1
ответ дан 1 December 2019 в 09:01
поделиться

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

1
ответ дан 1 December 2019 в 09:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: