如果我们已经使用了catch all Exception处理程序,我们是否可以通过添加null check获得任何好处?

时间:2017-05-05 05:49:54

标签: c#

这是.NET特有的 我正在编写一个代码片段,我必须使用catch all exception handler。我调用一系列可能返回null的函数。我不想继续,如果他们中的任何一个返回null,因为我有一个替代但昂贵的方法来获得相同的结果。我想知道我是否应该使用一系列空检查。 我的代码看起来像:

    var some_info = null;
    try{
        var a = GetA();
        if(a != null){
            var b = a.GetB();
            if(b != null){
                var c = GetC(b);
                if(c != null){
                    some_info = c.GetSomeInfo();
                }
            }
        }
        catch(Exception e){
            // cant do anything here but I need above code to be silent
        }
    if(some_info == null)
        some_info = GetSomeInfoFromHeavyMethod();

在C#中如果我们尝试使用null引用它会抛出异常,所以如果上面的任何变量都为null,则抛出NullReferenceException。因此我们可以编写上面的代码,如

    var some_info = null;
    try{
            var a = GetA();
            var b = a.GetB();
            var c = GetC(b);
            some_info = c.GetSomeInfo();
        }
        catch(Exception e){
            // cant do anything here but I need above code to be silent
        }
    if(some_info == null)
        some_info = GetSomeInfoFromHeavyMethod();

我的问题是,我应该在这里使用空检查还是让异常处理程序在这里工作?我的直觉是说我应该使用null检查,因为这是一个很好的做法但是,我有一个疑问,因为我必须在这里使用catch all exception handler,我已经承担了try / catch块的费用。

2 个答案:

答案 0 :(得分:7)

是的,我强烈建议使用空检查:

  • 它显示您期望值可以为null,并且这本身不是问题
  • 如果您曾在catch区块中添加日志记录,则可以轻松地执行此操作而不会被容易避免的消息发送垃圾邮件
  • 调试代码时,由于没有进行检查,您真的不希望调试器因NullReferenceException而停止
  • 你说你“已经承担了尝试/捕获块的成本” - 目前尚不清楚你是在谈论代码可读性成本还是性能成本,但基本上没有性能成本如果没有抛出异常,则为try / catch块。将其与 抛出异常的情况进行比较,这肯定会影响性能。

最终,我会认为每个NullReferenceException都是某个地方的错误 - 这种异常总是会导致您添加更多验证(例如抛出ArgumentNullException)或处理该值为空。你的代码就不会这样了。

通过一些重构,您可以使用C#6中引入的空条件运算符来减少代码。你最终可能会:

someInfo = GetA()?.GetB()?.GetC()?.GetSomeInfo();

答案 1 :(得分:2)

异常情况发生时应该抛出异常。所以,这一切都取决于你是否要考虑函数返回null异常的情况。没有硬性规定。

虽然我怀疑如果函数返回null而不是抛出异常,那么实现这些函数的人已经做出了某种选择,那就是不是特殊。但是当然,在你称之为这些功能的地方,你可能想要重新定义什么是特殊的,什么不是。

然而,有一点技术问题:抛出一个例外非常了解微软在C#上的实现,(可能也在Mono上?我不知道)所以我们不幸倾向于< em> not 考虑到某些情况异常(因此抛出异常)当选择为临界性能是一个问题时。