13

A colleague of mine just encountered an interesting problem. I recreated the issue with a simple example code below. The problem is that the compiler complains about i possibly not being assigned when it is used in the third line.

I know that GetProperty will not be executed, if o is null, and i will then not be initialized, but in that case I would also not evalueate int i2 = i;. Is there something about optionals or the null coalescing opertator I don't know that is relevant here, or is this simply a case where the compiler isn't intelligent enough to know that i is not used if it is not initialized?

void Test(object o) {
    if (o?.GetProperty("Blah", out int i) ?? false) {
        int i2 = i;
    }
}
Piflik
  • 333
  • 1
  • 10
  • I think the compiler just isn't that "smart". It can't make the conclusion that the "null propagation program path" `object o = null; if(o?.GetProperty("Blah", out int i) ..` will be caught by the `?? false` part of the if statement – mortb Feb 13 '19 at 09:36
  • @Piflik You could split out variable from argument and initialise there. – KrishnaDhungana Feb 13 '19 at 09:52

1 Answers1

6

you are using Null Conditional Access with o? which means that there is a possibility that (whenever o is null) GetProperty will not be called.

This introduces posibility of uninitialized i. because out int i won't be called in the case that o is null.

the code can be tested by removing null conditional access

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

on the above method, GetProperty method is always called and thus i is always initialized and assigned.


On the other hand your code does not compile, object o does not have .GetProperty method on its own


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

can be expanded as

if (o != null)
{
     if (o.GetProperty("Blah", out int i))
     {
     }
}
else
{
     //i is not defined in this context //
}
Derviş Kayımbaşıoğlu
  • 28,492
  • 4
  • 50
  • 72
  • Would the downvoter indicate why Simonare's answer is wrong? – ProgrammingLlama Feb 13 '19 at 09:28
  • 4
    @John I see no value in this answer. It just states a fact which OP is already aware of (as described in the question). – croxy Feb 13 '19 at 09:29
  • 1
    so what do you expect? I am describing how the compiler behaves. Do you have any other suggestion on this? The error is expected and logical as it is described above – Derviş Kayımbaşıoğlu Feb 13 '19 at 09:31
  • 2
    @Simonare Maybe adding why the compiler is not aware of the fact that the "true" path of the if statement will not be executed if `o` is NULL and therefore `i` uninitialized. Or something between those lines. I don't have a great answer either. – croxy Feb 13 '19 at 09:36
  • I know that I can't use uninitialized variables and also that `GetProperty` will not be executed if `o` is null, but the only line that uses the then uninitialized variable will also not be executed in that case. `GetProperty` is an extension method I wrote. It uses reflection to get the value of a property, but that is not important for the question, I just needed a function with an `out` parameter. – Piflik Feb 13 '19 at 09:37
  • 1
    @croxy can you please check my edited answer? – Derviş Kayımbaşıoğlu Feb 13 '19 at 09:52
  • @Simonare Have a look at https://stackoverflow.com/a/47685008/5453249 this answers OPs question perfectly in my opinion. – croxy Feb 13 '19 at 11:13
  • 1
    @Simonare in your expanded code example, the else block does not *use* `i`, and therefore there should be no compiler error. – Callum Watkins Feb 13 '19 at 14:02