Given this code:
private void TryIt(Dictionary<int, int> myDict)
{
if (myDict?.TryGetValue(1, out int myValue) ?? false)
{
Console.Out.WriteLine(myValue); // <-- Error CS0165
}
}
The c# compiler emits:
error CS0165: Use of unassigned local variable 'myValue'
But it is clearly not possible to reference myValue
when the call to TryGetValue()
is skipped by the ?.
operator. This is because the resulting null
is converted to false
by ?? false
.
In other words, if myDict
is null
, the ?.
operator will skip the call to TryGetValue()
, leaving myValue
unassigned. I get that.
BUT the ??
operator will then always evaluate that null propagation to false
, preventing entry into the if-block in this case.
This is evident at compile-time, so why the error?
I suspect that it probably has to do with how all this syntactic sugar is eventually unwound into actual .NET p-code, but it still seems wrong to error out...
When not using the .?
operator, I get no error, which is expected:
if (myDict.TryGetValue(1, out int myValue))
{
Console.Out.WriteLine(myValue); // <-- NO ERROR
}
It's just when I use .?
with ?? false
.
"But it is clearly not possible ..."
That is correct but the compiler does not track the logic that deeply.
The compiler could have deduced this, but note that the scope of myValue extends beyond the if statement:
if (myDict?.TryGetValue(1, out int myValue) ?? false)
{
Console.Out.WriteLine(myValue); // <-- Error CS0165
}
Console.Out.WriteLine(myValue); // myValue is in scope here
So while you might desire that the compiler figured out all the ?.
and ??
logic, and that the code inside the if () { ... }
is a special case, that apparently is a feature that wasn't deemed important enough.
myDict?.TryGetValue(1, out int myValue)
does not always assign to myValue
.