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

Resharper は私にSimplify conditional ternary expression. FirstOrDefault()しかし、nullを返す可能性があるため、ここでは null チェックが必要なように感じます。

では、私と 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もあるメソッドです。R# が常に null または非 null であることを自動的に解決しないように使用しました。nullFooRandom

さて、あなたがこの行で言うように:

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

R# はインスペクションSimplify conditional operatorを提供します。これはどういう意味ですか?さて、いつものように、Alt+Enterして提案を受け入れ、それを何に置き換えたいかを確認できます。この場合は次のようになります。

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

さて、あなたの懸念について:

しかし、FirstOrDefault() は null を返す可能性があるため、ここでは null チェックが必要だと思います。

では、私と Resharper のどちらが間違っているのでしょうか?

ええと、簡単に言えば、あなたはそうです。ここではまだ null チェックが行われており&&演算子は を短絡しているため、2 番目のオペランド ( foo.SomeBool)は、最初のオペランドが である場合にのみ評価されtrueます。NullReferenceExceptionしたがって、 isの場合にfooはa はありませんnull。最初のチェックは失敗し、bar割り当てられfalseます。

だから二行

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

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

意味的に同等であり、R# は通常より簡潔なバージョンを好みます (特に、明示的なtrues とfalse条件文の s は、多くの場合、冗長なコードのマークです)。そうでない場合は、このインスペクションをオフにすることができます。

于 2013-01-31T09:22:01.497 に答える
9

ReSharper は、コードを次のように変更することを提案しています。

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

三項演算とまったく同じですが、見栄えが良くなります。コードのロジックは変わりません。

于 2013-01-31T09:17:16.313 に答える