попытаться поймать плохую форму? - PullRequest
2 голосов
/ 27 сентября 2010

Я думаю, что знаю своего рода ответ на этот вопрос, но всегда есть много способов сделать что-то (некоторые из которых явно неправильны :)) ...

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

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

У меня есть код таким образом:

private Guid getMyEnabledManagersID(OnlineEmployee e)
    {
     Employee manager;
     try
     {
      //see if Employee e's manager is in the disabled list.
      manager = (from emp in EmployeesToDisable where emp.EmployeeID.Equals(e.ManagerID) select emp).Single();
      //yes they are, so need to call this again 
      return getMyEnabledManagersID(manager);
     }
     catch
     {
      return e.ManagerID;
     }
    }

Ответы [ 4 ]

6 голосов
/ 27 сентября 2010

Как уже отмечали другие , никогда не делайте этого .Это «худшая практика».Исключением является то, что в вашей программе есть логическая ошибка .Перехватывая исключение и продолжая, вы скрываете логическую ошибку.

Используйте Single, только когда вы знаете , точно и точно, что в последовательности ровно один элемент.Если в списке может быть другое количество элементов, используйте First, FirstOrDefault, SingleOrDefault или напишите свой собственный оператор последовательности;это не сложно сделать.

Основные причины не использовать эту худшую практику:

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

2) Использование исключений в качестве потока управления, подобного этому, затрудняет отладку программы.Отладчики часто настроены на остановку любого исключения, независимо от того, обрабатывается оно или нет.Многие «ожидаемые» исключения усложняют ситуацию.Никогда не следует ожидать исключений, они должны быть исключительные ;именно поэтому они называются «исключениями».

3) Улов ловит все, включая вещи, которые, вероятно, указывают на фатальную ошибку, о которой следует сообщить пользователю.

6 голосов
/ 27 сентября 2010

Оставляя в стороне рекурсию, возможно, вам следует просто использовать SingleOrDefault и проверить на ноль. На самом деле, вам вероятно не нужен полный объект сотрудника - вам, вероятно, достаточно просто вернуть идентификатор (повсюду), т. Е.

private Guid getMyEnabledManagersID(Guid managerId)
{
    var disabled = (from emp in EmployeesToDisable 
                    where emp.EmployeeID == managerId
                    select (Guid?)emp.ManagerID).SingleOrDefault();
    return disabled == null ? managerId : getMyEnabledManagersID(disabled.Value);
}

На самом деле, самая большая проблема , с которой я сталкиваюсь в исходной форме, заключается в том, что она не относится к типу исключения; это может быть "прерывание потока", "соединение зомби", "тупик" и т. д.

1 голос
/ 27 сентября 2010

Помимо других ответов,

Try / Catch - это очень дорогостоящие операции, ваш простой оператор if быстрее с точки зрения производительности, чем ожидание перехвата и последующая логика.

Try / Catch не должно быть частью бизнес-логики, вместо этого они должны быть только частью обработки ошибок.

0 голосов
/ 27 сентября 2010

Вы можете использовать FirstOrDefault () вместо Single и обрабатывать возвращенное нулевое значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...