C# 对何时抛出异常感到困惑
我正在开发一个库,该库设计用于与外部设备通信(通过RS232串行通信)。我在考虑错误处理策略,异常似乎是正确的,并且是报告错误的行业标准方法 所以我很少阅读关于例外情况的指南。非常明确地指出,我应该而不是担心性能问题: 不要使用错误代码,因为担心异常可能会对性能产生负面影响 告诉我在正常情况下不要抛出异常: 不要将异常用于正常或预期错误,或用于正常控制流 我无法在正常/预期和其他情况之间划清界限。例如,在我的库中,操作可能会失败,因为:C# 对何时抛出异常感到困惑,c#,.net,exception-handling,C#,.net,Exception Handling,我正在开发一个库,该库设计用于与外部设备通信(通过RS232串行通信)。我在考虑错误处理策略,异常似乎是正确的,并且是报告错误的行业标准方法 所以我很少阅读关于例外情况的指南。非常明确地指出,我应该而不是担心性能问题: 不要使用错误代码,因为担心异常可能会对性能产生负面影响 告诉我在正常情况下不要抛出异常: 不要将异常用于正常或预期错误,或用于正常控制流 我无法在正常/预期和其他情况之间划清界限。例如,在我的库中,操作可能会失败,因为: 设备没有响应。(未连接电缆,设备未打开,波特率错误) 操作
您认为我应该采用哪种方法?使用RS232,除非您启用了硬件握手功能(大多数情况下,人们都没有),否则您将看不到更多的数据从线路中输入。除了没有向PC发送任何信息之外,您无法判断设备是否已连接 我可能会将1和3一起归类为RS232TimeoutError,将2归类为RS232AuthenticationError 一般来说,TimeoutError表示远程设备已锁定或未连接。身份验证错误有点像协议错误,但微妙的区别在于通信正常,但远程设备“只是拒绝”与PC建立连接 我认为将这些设置为异常是合理的:在正常操作期间,您永远不会期望出现超时错误,也不会期望出现身份验证错误。您正在开发一个库,一个将由其他应用程序使用的组件 因此,在您提到的预期情况下,我肯定会使用异常来与调用应用程序进行通信,指出有问题。您应该为这些场景中的每一个定义一个自定义异常,然后清楚地记录它们可能发生的时间 然后,这允许应用程序客户机代码决定如何最好地继续。只有客户机应用程序才能做出此决定,并且清楚地记录异常会大大有助于这一点 自定义异常最好的一点是,您可以提供与问题/异常相关的多个有意义/有用的数据段。这些数据也很好地封装在一个对象中。将其与错误代码和返回值进行比较 性能可能是一个问题,但只有在紧循环或其他高活动性情况下引发异常时才会出现。为了避免这种情况,您还可以应用.NET Framework使用的模式,即提供Try….()方法(例如
TryParse()
),该方法返回布尔值,指示操作是成功还是失败
无论哪种方式,我都会先使用自定义异常,然后进行性能测试,以实际查看库中是否有某些部分需要优化。是否引发异常是函数类型的结果
- 如果函数返回一个X,而您无法确定一个有效的X,则抛出一个异常
- 如果函数是一个操作(如Connect),而您未能完成该操作,则引发异常
- 如果函数是TryX类型,则不要抛出异常
所以我想我是说你应该把问题从“我应该抛出一个异常吗?”推到“调用我的库的人想要什么方法?”并警告说,根据你提供的方法,你抛出的异常应该是明显的(灵感来自合同设计)
- 如果可能,请提供布尔值 检验职能部门告诉你 手术是否能安全进行 应用 对于给定的操作,考虑 这样一种检查功能,如 前提条件:如果成立,则 操作可以安全完成,如果不能,您可以 抛出异常
- 见M.Bruntink,A.van Deur
Public Function Nz(ByVal value As String, ByVal valueIfNothing As String) As String Try Dim sValue As String = System.Convert.ToString(value) 'using Convert.ToString on purpose If IsNothing(sValue) Then Return valueIfNothing Else Return sValue End If Catch ex As Exception 'Convert.ToString handles exceptions, but just in case... Debug.Fail("Nz() failed. Convert.ToString threw exception.") Return String.Empty End Try End Function
Public Function Nz(ByVal value As String, ByVal valueIfNothing As String) As String Dim sResult As String = String.Empty Dim sValue As String = System.Convert.ToString(value) 'using Convert.ToString on purpose If IsNothing(sValue) Then sResult = valueIfNothing Else sResult = sValue End If Return sResult End Function