var foo = context.FOOTABLE.FirstOrDefault();
var bar = foo != null ? foo.SomeBool : false;
Resharper告诉我Simplify conditional ternary expression
。但我觉得这里需要进行空检查,因为FirstOrDefault()
可以返回null。
那么,谁错了,我还是Resharper?
答案 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
。因此,当NullReferenceException
为foo
时,不会有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;
与三元操作完全相同,但看起来更好。代码的逻辑不会改变。