Вот пример приложения, которое я пишу:
bool x3k = false, y3k = false;
// all of these functions return nullable ints (int?)
var comparison =
DoSomething(x, y)
?? DoSomething2(x, y)
?? DoSomething3(x, y, out x3k, out y3k)
?? DoSomething4(x, y)
?? DoSomething5(x, y);
if (comparison.HasValue)
return comparison.Value;
if (x3k) // compiler error here if I don't init x3k
{
}
Я не понимаю, в цепочке нулевых коалесценций, как x3k может быть неинициализирован, если comparison
равно null
и я не вернусь раньше. Что здесь происходит?
Вы столкнулись с поведением короткого замыкания: если DoSomething
или DoSomething2
возвращают что-то ненулевое, DoSomething3
никогда не будет выполняться, оставив x3k
и y3k
неинициализированными.
DoSomething
или DoSomething2
возвращают ненулевые значения, x3k
и y3k
никогда не будут доступны, так как я возвращаюсь раньше, если есть ненулевое значение.
Ваша программа расширена компилятором следующим образом:
bool x3k;
bool y3k;
var comparison = DoSomething(x, y);
if (!comparison) {
comparison = DoSomething2(x, y);
if (!comparison) {
comparison = DoSomething3(x, y, out x3k, out y3k);
if (!comparison) {
comparison = DomeSomething4(x, y);
if (!comparison) {
comparison = DoSomething5(x, y);
}
}
}
}
if (comparison.HasValue) return comparison.value;
if (x3k) {/* ... */}
if
гнездо будет разбито, как только одна из функций вернет что-то ненулевое. Если DoSomething3
не запускается, x3k
не инициализируется. comparison.HasValue
будет true
как только одна из функций вернется непустой, но компилятор рассматривает это свойство как нечто не определяемое во время компиляции. Поэтому он считает, что comparison
может быть нулевым, а x3k
не инициализироваться.
comparison
null
, x3k
никогда не будет доступен.
DoSomething
возвращает ненулевое значение, как вообще будет вызыватьсяDoSomething3
? ЕслиDoSomething3
не вызывается, как инициализируются эти переменные? Нулевое слияние - это короткое замыкание.