Факультативное нулевое слияние в предложении if

Мой коллега только что столкнулся с интересной проблемой. Я воссоздал проблему с простым примером кода ниже. Проблема в том, что компилятор жалуется на то, что i возможно, не назначен, когда он используется в третьей строке.

Я знаю, что GetProperty не будет выполняться, если o равно null, и i не буду инициализирован, но в этом случае я бы также не оценивал int i2 = i; , Есть ли что-то в опциях или пустом объединяющем операторе, я не знаю, что здесь уместно, или это просто тот случай, когда компилятор не достаточно умен, чтобы знать, что i не используется, если он не инициализирован?

void Test(object o) {
    if (o?.GetProperty("Blah", out int i) ?? false) {
        int i2 = i;
    }
}

Ответ 1

Вы используете нулевой условный доступ с o? Это означает, что существует вероятность того, что (когда o имеет значение null), GetProperty не будет вызываться.

Это вводит возможность неинициализированного i. потому что out int i не буду вызываться в случае, если o равно нулю.

код можно протестировать, удалив нулевой условный доступ

void Test(SomeClass o) {
    if (o.GetProperty("Blah", out int i) ?? false) {
        int i2 = i; //no-compiler error 
    }
}

в приведенном выше методе метод GetProperty всегда вызывается и, следовательно, i всегда инициализируется и присваивается.


С другой стороны, ваш код не компилируется, object o не имеет метода .GetProperty по себе


if (o?.GetProperty("Blah", out int i) ?? false)

может быть расширен как

if (o != null)
{
     if (o.GetProperty("Blah", out int i))
     {
     }
}
else
{
     //i is not defined in this context //
}