Ответ 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
в условных обозначениях часто являются меткой избыточного кода). Вы не можете, и в этом случае вы можете отключить эту проверку.