尝试抓坏形式?

nat*_*nat 2 c# asp.net exception-handling

我想我有点知道这个问题的答案,但总有很多方法可以做(有些方法显然是错的:))...

我有一个递归功能来查找员工经理的ID.这是在导入脚本中使用的,可能是直接经理人离开(被禁用)所以我们需要找到员工(经理)经理(等等),以便我们可以为他们分配东西.如果不明显,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;
     }
    }
Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 6

抛开递归,你应该只使用SingleOrDefault并测试null.实际上,您可能不需要完整的员工对象 - 您可以只返回id(整个),即

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);
}
Run Code Online (Sandbox Code Playgroud)

实际上,我对原始形式的最大担忧是它不是特定于异常的类型 ; 它可能是"线程中止","僵尸连接","死锁"等.


Eri*_*ert 6

正如其他人指出,从来没有做到这一点.这是"最糟糕的做法".例外情况是告诉您程序中存在逻辑错误.通过捕获异常并继续,您可以隐藏逻辑错误.

只有在您确切地知道序列中只有一个元素时才使用Single .如果列表中可能有其他数量的元素,则使用First,FirstOrDefault,SingleOrDefault或编写自己的序列运算符; 这不难做到.

不使用这种最差做法的主要原因是:

1)正如我所说,它隐藏了一个错误; 永远不应该抓住这些例外,因为它们永远不应该被投入到工作程序中.有例外可以帮助您调试程序,而不是控制它的流程.

2)使用异常作为这样的控制流使得调试程序变得困难.调试器通常配置为在任何异常时停止,无论是否处理.很多"预期的"例外使得更难.绝不应该例外,它们应该是特殊的 ; 这就是为什么他们被称为"例外".

3)捕获捕获所有内容,包括可能表示应向用户报告的致命错误的内容.