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

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

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

4

2 回答 2

37

首先,一个完整的例子:

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# 不会自动确定它始终为空或非空。

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

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

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

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

现在,关于您的担忧:

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

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

好吧,简而言之,你就是。这里仍然会进行空值检查,并且运算&&符是短路的,所以第二个操作数 ( foo.SomeBool)只有在第一个是 时才会被计算trueNullReferenceException所以在 when foois的情况下不会有 a null;第一次检查将失败,bar将被分配false

所以这两行

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

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

are semantically equivalent, and R# as usual prefers the more concise version (in particular, explicit trues and falses in conditionals are often a mark of redundant code). You may not, in which case you could turn off this inspection.

于 2013-01-31T09:22:01.497 回答
9

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

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

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

于 2013-01-31T09:17:16.313 回答