“简化条件三元表达”

时间:2013-01-31 09:01:57

标签: c# asp.net resharper

var foo = context.FOOTABLE.FirstOrDefault(); 
var bar = foo != null ? foo.SomeBool : false;

Resharper告诉我Simplify conditional ternary expression。但我觉得这里需要进行空检查,因为FirstOrDefault()可以返回null。

那么,谁错了,我还是Resharper?

2 个答案:

答案 0 :(得分:31)

首先,一个完整的例子:

class Foo
{
    public bool SomeBool { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var foo = MaybeFoo();

        var bar = foo != null && foo.SomeBool;

    }

    static Foo MaybeFoo()
    {
        return new Random().Next() < 10 ? null : new Foo();
    }
}

此处MaybeFoo是一种有时会返回null并有时会返回Foo的方法。我使用了Random,因此R#不会自动计算出它始终为null或不为null。

现在,正如你在这一行所说:

        var bar = foo != null ? foo.SomeBool : false;

R#提供检查简化条件运算符。这是什么意思?好吧,像往常一样,我们可以 Alt + 输入并接受建议并查看它想要替换它的内容,在这种情况下是:

        var bar = foo != null && foo.SomeBool;

现在,关于你的担忧:

  

但我觉得这里需要进行空检查,因为FirstOrDefault()可以返回null。

     

那么,谁错了,我还是Resharper?

好吧,不久之后,你就是。这里仍然进行空检查,并且 &&运算符正在短路,因此第二个操作数(foo.SomeBool只会在第一个时进行评估一个是true 。因此,当NullReferenceExceptionfoo时,不会有null;第一次检查将失败,bar将被分配false

所以两行

        var bar = foo != null ? foo.SomeBool : false;

        var bar = foo != null && foo.SomeBool;

在语义上等效,而R#通常更喜欢更简洁的版本(特别是显式true和条件中的false s通常是多余的标记码)。您可能不会,在这种情况下您可以关闭此检查。

答案 1 :(得分:9)

ReSharper建议将您的代码更改为:

var bar = foo != null && foo.SomeBool;

与三元操作完全相同,但看起来更好。代码的逻辑不会改变。