Подтвердить что ты не робот

"Упростить условное тернарное выражение"

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

Resharper сообщает мне Simplify conditional ternary expression. Но мне кажется, что здесь нужна нулевая проверка, так как FirstOrDefault() может возвращать null.

Итак, кто не прав, я или решар?

4b9b3361

Ответ 1

Во-первых, полный пример:

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.

Итак, кто не прав, я или решар?

Что ж, если коротко, то вы. Здесь все еще выполняется нулевая проверка, а оператор && замыкает, поэтому второй операнд (foo.SomeBool) будет оцениваться только в том случае, если первый true. Таким образом, в случае, когда Foo null, не будет NullReferenceException; первая проверка завершится неудачей, а bar будет присвоено false.

Итак, две строки

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

и

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

являются семантически эквивалентными, а R # как обычно предпочитает более краткий вариант (в частности, явные true и false в условных обозначениях часто являются меткой избыточного кода). Вы не можете, и в этом случае вы можете отключить эту проверку.

Ответ 2

ReSharper предлагает изменить ваш код на:

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

Что точно так же, как тройная операция, но выглядит лучше. Логика вашего кода не изменится.