Когда уместно использовать метод ThrowHelper вместо того, чтобы бросить непосредственно?
void MyMethod() {
...
//throw new ArgumentNullException("paramName");
ThrowArgumentNullException("paramName");
...
}
void ThrowArgumentNullException(string paramName) {
throw new ArgumentNullException(paramName);
}
Я считал, что вызов метода ThrowHelper (метод с единственной целью выдать исключение) вместо того, чтобы бросить непосредственно должен привести к меньшему байт-коду.
Это и очевидная инкапсуляция (другой слой косвенности), могут быть серьезными основаниями не бросить непосредственно, по крайней мере, в некоторых сценариях.
Так или иначе IMO недостатки являются весьма существенными также.
Мой ограниченный опыт состоит в том, что часто общий замысел ухудшается.
int MyMethod(int i) {
switch (i) {
case 1:
return 1;
default:
ThrowMyException();
}
return 0; // Unreachable (but needed) code
}
Это может частично быть вопросом персонального вкуса. Так или иначе, каковы Ваши персональные инструкции об этой проблеме? Вы находите, что это - хорошая идея использовать ThrowHelpers для всех тех общих задач как проверка параметрического усилителя метода (ThrowArgumentNullException (paramName) и такой)? Я пропускаю что-то очевидное по этой проблеме?
Btw я пытаюсь не смешать эту проблему с проблемой проверки, например, метод как:
ThrowIfNameIsNullOrEmpty(name);
Мой подход по умолчанию - бросать непосредственно из исключительной ветви кода.
Принцип 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);
}
Это сохраняет след стека.
.Мне кажется, что это ненужная абстракция. У вас есть метод, который делает одно, названный так же многословно, как и то, что он делает.
Аргумент о меньшем количестве байткодов практически бессмысленен, так как размер вашего кода редко имеет значение (вы бы не сэкономили больше килобайта на экземпляр вашей программы, если только не выбросите это исключение из нелепого числа мест в вашем исходном коде). Между тем все указанные вами недостатки являются реальными проблемами, особенно когда речь идет о ясности обработки исключений.
В основном абстрагирование таких мелких вещей, как это, обычно возвращается, чтобы укусить вас. (Некоторое увлекательное чтение на эту тему: http://www.joelonsoftware.com/articles/LeakyAbstractions.html)
Я бы сказал, что единственное разумное время для этого - в чем-то вроде BCL, где количество использования класса достаточно велико, чтобы экономия могла быть того стоить. Однако это должно иметь смысл. В вашем случае, я не думаю, что вы действительно экономите место. Примеры ThrowHelper в BCL уменьшают размер, заменяя перечисления на строки и вызовы методов (для получения строковых сообщений). В вашем случае просто передаются одни и те же аргументы и, таким образом, экономия не достигается. Вызов метода стоит столько же, сколько и бросание исключения на место.
.Я всегда стараюсь бросать свои собственные исключения только с целью настройки. Я могу бросить сообщение, которое вкратце расскажет мне, в чем проблема (и, возможно, откуда она взялась). Что касается проблем с производительностью, я стараюсь максимально ограничить количество исключений, бросаемых на release версиях моих программ, так что на самом деле я никогда не задумывался об этом слишком много. Мне интересно посмотреть, что скажут другие.
Это мои 2 цента. Пожалуйста, примите это как должное
.Из того, что я понял, меньший байт-код - это практически единственное преимущество ( Смотрите этот вопрос), так что я не ожидаю, что вы увидите много аргументов в ответах здесь.