_var foo = context.FOOTABLE.FirstOrDefault();
var bar = foo != null ? foo.SomeBool : false;
_
Resharperは私に_Simplify conditional ternary expression
_と言っています。しかし、FirstOrDefault()
はnullを返す可能性があるため、ここではnullチェックが必要だと思います。
それで、私とResharperのどちらが間違っているのですか?
まず、完全な例:
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またはnot-nullであると自動的に判断されません。
さて、あなたがこの行で言うように:
var bar = foo != null ? foo.SomeBool : false;
R#は検査を提供します条件演算子を単純化します。これはどういう意味ですか?まあ、いつものように、私たちはできます Alt+Enter 提案を受け入れて、それを何に置き換えたいかを確認します。この場合は次のとおりです。
var bar = foo != null && foo.SomeBool;
さて、あなたの懸念について:
しかし、FirstOrDefault()はnullを返す可能性があるため、ここではnullチェックが必要だと思います。
それで、私とResharperのどちらが間違っているのですか?
まあ、簡単に言えば、あなたはそうです。ここではまだnullチェックが行われています。&&
演算子が短絡していますなので、第2オペランド(foo.SomeBool
)最初のものがtrue
の場合にのみ評価されます。したがって、NullReferenceException
がfoo
の場合、null
は存在しません。最初のチェックは失敗し、bar
にはfalse
が割り当てられます。
だから2行
var bar = foo != null ? foo.SomeBool : false;
そして
var bar = foo != null && foo.SomeBool;
は意味的に同等であり、R#は通常、より簡潔なバージョンを優先します(特に、条件文の明示的なtrue
sとfalse
sは冗長コードのマークであることがよくあります)。そうしない場合は、この検査をオフにすることができます。
ReSharperは、コードを次のように変更することを提案しています。
var bar = foo != null && foo.SomeBool;
これは三項演算とまったく同じですが、見た目は良くなります。コードのロジックは変更されません。