尝试抓坏形式?

时间:2010-09-27 09:48:32

标签: 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;
     }
    }

4 个答案:

答案 0 :(得分: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);
}

实际上,我对原始表单的最大关注点是它并不特定于异常的类型;它可能是“线程中止”,“僵尸连接”,“死锁”等等。

答案 1 :(得分:6)

正如其他人指出的那样从不这样做。这是“最糟糕的做法”。例外情况是告诉您您的程序中存在逻辑错误。通过捕获异常并继续,您可以隐藏逻辑错误。

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

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

1)正如我所说,它隐藏了一个错误;这些异常应该从不被捕获,因为它们永远不会被抛入工作程序中。有例外可以帮助您调试程序,而不是控制它的流程。

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

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

答案 2 :(得分:1)

除了其他答案,

Try / Catch是非常昂贵的操作,简单的if语句在性能方面更快,然后期望捕获然后遵循逻辑。

Try / Catch不应该是业务逻辑的一部分,而应该只是错误处理的一部分。

答案 3 :(得分:0)

您可以使用FirstOrDefault()而不是Single并处理返回的空值。

相关问题