C#错误代码与exception

我有一个控制电路,我通过串口进行通信。 如果响应命令与某种格式不匹配,我认为它是一个错误,并想知道我是否应该返回错误代码或抛出exception? 例如:

public double GetSensorValue(int sensorNumber) { ... string circuitCommand = "GSV,01," + sensorNumber.ToString(); // Get measurement command for specified sensor. string responseCommand; string expectedResponseCommand = "GSV,01,1,OK"; string errorResponseCommand = "ER,GSV,01,1,62"; responseCommand = SendReceive(circuitCommand); // Send command to circuit and get response. if(responseCommand != expectedResponseCommand) // Some type of error... { if(responseCommand == errorResponseCommand) // The circuit reported an error... { ... // How should I handle this? Return an error code (eg -99999) or thrown an exception? } else // Some unknown error occurred... { ... // Same question as above "if". } } else // Everything is OK, proceed as normal. ... } 

谢谢!

几乎所有情况下,我都会通过exception传达错误。 我几乎从不使用“错误代码” – 有时候在int.TryParse等中给出成功/失败以及结果是int.TryParse ,但我不认为这种情况是这样的。 这听起来像一个真正的错误条件,应该停止进一步的进展,所以一个例外是适当的。

编辑:如评论中所述,如果报告错误的电路确实是“预期的”并且调用者应该能够处理它并且应该主动寻找那种情况,那么使用状态代码是合理的。

不幸的是,error handling是我们在软件工程中还没有真正做到的事情之一……

严格地说,当你处于“特殊”环境时,即你不会期望的情况下,会使用例外。

如果是我,我可能会在第一种情况下返回错误代码(已知错误响应),并在第二种情况下抛出exception(未知错误代码)

在你的情况下抛出exception更好。 因为该方法的调用者可以区分“合法”输出和错误条件。 如果返回错误代码,它仍然是一个数值,因此调用者可能会将其误解为控制电路的输出。

就个人而言,我喜欢通过定义某种响应对象来处理这种情况。 我已经通过这样的经验来衡量这一点并权衡应该被视为特殊的东西。 如果您正在与某些设备连接并且用户关闭设备或其他设备,这是一个例外情况,您将抛出exception。

如果对设备的特定方法调用失败或某事,那不是特别的,但这是一个错误。 如果我返回一个double,我不想定义一个幻数,我不想抛出exception。 所以,我定义了类似的东西:

 class DeviceResult //could also be struct { public double ReturnValue { get; set; } public bool IsValid { get; set; } public string ErrorMessage { get; set; } } 

这里的细节并不重要 – 您将根据您的方法所需的客户进行调整。 在此示例中,客户端API将检查是否有效,如果是,则使用返回值 – 没有幻数,也没有exception。 范式更重要。 我看到它的方式,你使用面向对象的语言 – 所以你不妨使用对象。 🙂

错误代码。

  1. 抛出exception比返回值慢。
  2. 您可以自由设计方法签名,因此您可以返回所需的任何类型。 如果你必须返回一些无法以有意义的方式扩展的特定类型,那么你肯定不得不抛出exception。
  3. 在调用方法时,忽略exception比忽略错误代码更容易。 您必须记录您的方法抛出的exception,并希望其他开发人员阅读它。
  4. GetSensorValue方法的响应具有不同的路径。 “快乐的道路”显然是预期的,也是最有趣的。 但是如果你知道消费者可以处理不那么繁琐的路径的结果,那么使用错误代码是有意义的,因为更“预期”的“不快乐的路径”响应。
  5. 抛出大量exception会导致您的debuger不断中断,具体取决于您的调试器exception设置。
  6. 返回错误代码肯定会使您的响应类型更复杂,这需要更多代码来解包该值。 但是,读取和写入“if(response.Status == Statuses.Success){var value = response.Value;}”而不是try-catch真的很难吗?

抛出exception是一种好习惯:

  1. 当您可以预见您的方法调用将失败时(检查您是否可以在执行之前执行操作)。 可以实现“执行”方法以返回错误代码,但是这种检查执行方法对被认为是模式。
  2. 您无法以有意义的方式扩展响应类型,但您需要在方法合同未预见的状态下发出响应信号。
  3. 与之前类似,您有充分的理由只返回“快乐路径”结果。

由于一些简单的事实,我建议在大多数情况下使用例外:

  1. exception是全局的,所有C#开发人员都知道exception是什么(并且希望如何)将其用于调试。
  2. exception突破所有调用方法到最近的“try catch”。 如果我有几个层并且最内层抛出一个exception,那么我可以在任何我想要的层(通常是最外层或第二个最外层)处理该exception。
  3. 大多数项目类型都有某种可覆盖的方法或事件,可以覆盖/订阅以实现简单的全局exception处理代码。 这样可以很容易地格式化错误消息,执行记录,发送邮件并向众神祈祷(或者当你处理exception时你做的任何事情;))。

但有几件事需要考虑:

  1. 抛出exception并不是免费的。 如果您的代码需要100%优化,那么抛出exception可能是您希望避免的。
  2. 例外有很多你可能不需要的信息。 如果您只想向用户显示简单的错误消息,您真的需要堆栈跟踪吗?

但作为一般规则,我会说:坚持Exceptions,它简单,信息丰富,可调试且易于处理,即使它可能会有轻微的性能成本