在c#中捕获异常时要返回什么

时间:2015-02-17 17:34:14

标签: c#

这可能是一个非常简单的问题,但是try-catch块上的返回类型的最佳实践是什么?目前,我正在做这样的事情:

 public List<SomeAttribute> FindAttributes(int id)
   {
       try
       {
            //Some query and some logic
       }
       catch (Exception ex)
       {
           Logger.Error(ex);
           return new List<SomeAttribute>();
       }
   }

这有什么特别糟糕的吗?异常将被记录,该方法将返回一个空列表 - 调用函数可以处理。返回null更好吗?如果是这样的话?

1 个答案:

答案 0 :(得分:6)

一般来说,我们会考虑三种策略来处理部分功能(只有输入域的子集有效的功能):总计防御性 Nominal

总计

这意味着你总是回答答案。在这种情况下,您可以考虑返回 null - 指针,对于String.IndexOf,例如一个返回-1

<强>优点:

  • 调用者有时更容易不去考虑潜在的错误。有时返回值可能很有用。例如,如果你想切断字符串的第一部分(包括第一个逗号),你可以将其编码为:

    string foo = "Foo,Bar"
    string foocut = foo.SubString(foo.IndexOf(',')+1); //Bar, in case no comma, it returns the entire string
    

    从而产生更紧凑的代码。但另一方面,有时很难确定最佳回报值是什么。

<强>缺点:

  • 需要 engineering 来确定&#34; 最佳&#34;回报价值。有很多选项,每个选项只对部分呼叫者有利。
  • 有时候无法区分出现错误的有效输出和出现问题时的(默认)输出。

防御

在这里抛出异常(或不要抓住异常)。由特定于域的调用者决定为什么抛出异常并准确处理。 Util方法通常对系统知之甚少,因此不知道异常发生的原因。

<强>优点:

  • 可以由具有最佳知识的呼叫者处理异常(因此某种&#34; 责任链&#34;)。这可以导致更好的错误处理(向用户提供有用的消息)。不是&#34; SQL查询中发生错误... &#34;,但&#34; 用户名已存在。&#34;

<强>缺点:

  • 错误处理有时很难。特别是在C#中,一个人不需要注释方法可以抛出哪个异常。要涵盖所有类型的例外情况并不容易。未捕获的异常可能会返回到顶级Main调用,从而导致应用程序崩溃。对于像网络服务器这样的应用程序,这并不总是一种选择。

标称

在此处记录您的方法并提供预先编码:在您指定的文档中,使用该方法的正确方法是什么。这并不总是可行的,因为有时方法成功的事实取决于外部因素(服务器的可用性,OS的类型,......)。程序员不一定控制的因素。

<强>优点:

  • 结果记录良好(有时是严格的)定义方法。
  • 实现方法( callee )更容易,因为它可以假设一切都能正常工作。

<强>缺点:

  • 并非总是可能(有时结果取决于无法控制的因素)。
  • 编写调用者更难,因为它有一个合约,它只会使用正确的参数调用该方法。
  • 记录所有条件以及验证每个呼叫是否满足它们也很困难。有时代码合同用于处理验证(部分)自动。

大多数计划并不坚持使用一种策略,而是将它们混合使用:例如,一些例外处理总计,其他例外处理,其他处于防御状态。或者某些模块遵循防御策略,而另一个模块使用名义编程。