什么时候更好地抛出一个异常,什么时候更好地返回一些错误日志'对象'?

时间:2011-04-18 07:49:29

标签: c# exception error-handling status

我想知道如何决定:

1)如果要抛出自定义异常或

2)返回一种LOG对象,其中包含'CityNotFound','ReferenceConstraintBroken'等标志。

我一直在阅读例外是昂贵的。如果我只需要知道过程结果的具体细节,对我来说,拥有一个只包含过程的必要信息的自定义“过程LOG对象”听起来更有益。

所以,如果我回到 我的问题

什么时候最好抛出一个异常,何时更好地返回一些错误日志'object'?

5 个答案:

答案 0 :(得分:15)

抛出异常以提供更多信息(异常类型,消息等)以便正确处理并表示:

  1. 您的代码使用不当/非法
    1. 即。反对在编译期间无法强制执行的合同约束
  2. 发生了主流的替代方案
    1. 即。您希望操作成功但失败,例如获取资源或连接
  3. 我实际上不鼓励返回“日志对象”(即返回异常对象而不是抛出一个),因此

    1. 会导致if语句不必要的混淆,以检查结果并处理潜在错误
      1. 你的所有方法都必须返回一个“日志对象”(或者有一个out参数),否则你不能“冒泡”错误/异常进行范围处理,导致进一步的限制
    2. 失去了try / catch / 最终
    3. 的帮助
    4. 会损害范围的可读性(操作尝试与错误处理与清理)
    5. 如果你想返回“日志对象”,你应该使用布尔返回值和有意义的方法(即FindCity)或带有out布尔参数的方法(即TryFindCity )。这样,您不需要指定标志,只需使用其布尔返回允许您确定将要标志值的方法。

      修改

      根据OP的评论,如果有一个巨大的方法有许多可能的验证错误,那么应该重构巨大的方法来调用每个抛出适当异常的较小方法。然后,巨大的方法可以简单地重新抛出每个异常,或者只是让每个异常冒出来,如果它不应该是处理它的那个异常。

      如果存在阻止“正确分离”的验证依赖项,则只需使用正确的参数抛出一个ValidationException。下面是这个课程的一个例子:

      public class ValidationException : Exception {
          private readonly object _Field;
          public object Field { get { return _Field; } }
      
          public ValidationException(string message) : base(message) { }
      
          public ValidationException(string message, object field)
              : this(message) {
              _Field = field;
          }
      }
      

      然后你可以抛出一个解释验证错误的异常。

答案 1 :(得分:5)

如果您担心异常的性能,可以考虑“测试人员”模式,在大多数情况下可以用它来避免它们(它还使代码比try / catch中的更具可读性)我的意见)。

// Traditional try catch
try
{
    var record = myDb.myTable.Select(primaryKey);

    // do something with record...
}
catch (RecordNotFoundException)
{
    // The record not found in the database... what to do?
}

// Tester-doer pattern
if (myDb.myTable.RecordExists(primaryKey))
{
    var record = myDb.myTable.Select(primaryKey);

    // do something with record...
}
else
{
    // The record not found in the database... what to do?
}

同样的结果,没有例外。成本是你必须自己编写“RecordExists”函数,通常它就像做返回COUNT FROM myTable WHERE PrimaryKey = foo == 1

这样简单

答案 2 :(得分:3)

略微转过头来。考虑一下,我是否知道如何在函数中处理这个条件,并且代码会被频繁调用以使其值得一试,或者更一般地说,这是非常特殊的吗?

如果在您的函数的例程操作中出现这种情况,则将其作为返回值的一部分进行处理。如果因为您的函数被滥用或某些资源不可用而发生抛出​​异常。

答案 3 :(得分:2)

如果调用者可以阻止异常(比如知道该城市不存在),则抛出异常。否则返回错误。

我永远不会返回log个对象。它使代码不可读,因为你必须在任何地方添加if语句和特殊处理。最好添加CheckIfCityExists等方法。

答案 4 :(得分:1)

一般来说,只有在出现绝对意外的情况时才会返回异常。如果你知道并且可能发生这种情况,那么你应该尝试通过发送错误代码来处理它,或者更好地处理它,将代码格式化为较小的片段,

实施例

  1. 检查城市是否找到的方法调用
  2. 继续其他陈述