if...else
Является ли типичное завершение с обработкой исключений чем-то вроде следующего примера рекомендуемой практикой во избежание дублирования кода?
try
{
if (GetDataFromServer())
{
return ProcessData();
}
else
{
throw new Exception();
}
catch(Exception ex)
{
return null;
}
вместо...
try
{
if (GetDataFromServer())
{
return ProcessData();
}
else
{
return null;
}
}
catch(Exception ex)
{
return null;
}
Я знаю, что есть небольшое снижение производительности, но мне интересно, считается ли это приемлемой практикой. В настоящее время я делаю это вторым методом - особенно в тех случаях, когда мне нужно по-разному обрабатывать определенные исключения - но мне было интересно, подходит ли первый метод для простых случаев.
c#
exception-handling
grovesNL
источник
источник
Ответы:
Microsoft не рекомендует использовать обработку исключений для управления потоком.
И круглый стол по теме доступен.
При этом C # поддерживает это, и я полагаю, что это зависит от того, с каким условием столкнулся, является ли исключение наиболее подходящим ответом.
источник
Повышение производительности, скорее всего, незначительно, как объясняется в этом ответе .
Итак, давайте предположим, что производительность не является проблемой. Вы бросаете
System.Exception
, просто чтобы переместить исполнение вcatch
пункт . БросатьBadControlFlowThatShouldBeRewrittenException
, вероятно, было бы излишним.Давайте разберемся с этим. У нас есть:
GetDataFromServer
(имена методов должны быть PascalCase в C #), который может вызвать исключение или вернуть abool
.true
, бегиProcessData
.null
противном случае.Похоже, метод, в котором написан этот код, просто делает слишком много вещей.
GetDataFromServer
возвращаяbool
внешний вид как недостаток дизайна, я ожидал бы, что этот метод вернет данные, которые он получает с сервера , некоторые изIEnumerable<SomeType>
которых будут содержать 0 или более элементов - т.е. счастливый путь возвращает n элементов, где n> 0 , не такой счастливый path возвращает 0 элементов, а несчастный путь разрывается с необработанным исключением, что бы это ни было.Это сильно меняет внешний вид метода - опять же трудно сказать, имеет ли это смысл, потому что исходный пост имеет только одну точку выхода (и, следовательно, не будет компилироваться, так как не все пути кода возвращают значение ), поэтому это только дикая догадка:
Здесь вы посмотрите
ProcessData
и увидите, что он выполняет итерациюresult
, и возвращает,null
если вIEnumerable
.Теперь, почему метод возвращается
null
? Сервер не работает? Есть ли ошибка в запросе? Строка подключения использует неправильные учетные данные? Всякий раз, когдаGetDataFromServer
взрывается с исключением, которого вы не ожидаете, вы глотаете его, суете его под ковер и возвращаетеnull
значение. Я бы порекомендовал отлавливать конкретные исключения в этом случае и регистрировать все остальное; отладка будет намного проще.С общим
catch
предложением, которое не фиксирует исключение, довольно сложно что-либо диагностировать. Я бы минимально сделал это вместо этого:Теперь вы можете по крайней мере сломать и проверить,
e
если что-то пойдет не так.TL; DR : Нет, выбрасывать и перехватывать исключения для управления потоком данных не очень хорошая идея.
источник
в вашем первом ответе есть падение производительности, которое не должно быть там.
когда вы выходите из оператора if, чтобы войти в оператор Catch, когда вам не нужно заставлять код, так сказать, переключать направления.
если вы хотите
return null;
сделать это в операторе else, а не в подвохе, который перехватывается после выброса из оператора else.Возможно, это не относится к вашему реальному коду, но для общего кода, который вы дали, он действительно применим.
Стандарты говорят, что вы не должны этого делать.
Стандарты говорят, что вы должны делать это так (опять же на основе общего кода, указанного в OP)
и так как у вас нет никаких особых исключений, которые вы ловите, вам даже не нужно пытаться поймать здесь.
вы хотите видеть исключения, когда они возникают, чтобы вы могли исправить проблему, которая создает исключение.
источник
Почему не намного проще:
Если обработчик исключений будет существовать, он должен быть в ProcessData ()
источник
ProcessData()
на самый верхний уровень?ProcessData()
выбрасывает исключение, оно не обрабатывается. Я хочу этоreturn null
на этом уровне, еслиProcessData()
выдает исключение, не изменяяProcessData()
себя.