FMM
FMM

Reputation: 4329

C# Compiler thinks these variables should be initialized

Here is a sample of an application that I'm writing:

        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
        {

        }

I don't understand, in the null coalescing chain, how x3k could be uninitialized if comparison is null and I don't return early. What's going on here?

Upvotes: 1

Views: 121

Answers (2)

Ben N
Ben N

Reputation: 2923

Your program is expanded by the compiler into this:

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) {/* ... */}

The if nest will be broken out of as soon as one of the functions returns something non-null. If DoSomething3 does not run, x3k is not initialized. comparison.HasValue will be true as soon as one of the functions returns non-null, but the compiler treats that property as something not determinable at compile time. Therefore, it thinks comparison could be null and x3k to not be initialized.

Upvotes: 3

Cory Nelson
Cory Nelson

Reputation: 30031

You are encountering short-circuit behavior: If DoSomething or DoSomething2 return something non-null, DoSomething3 will never execute, thus leaving x3k and y3k uninitialized.

Upvotes: 5

Related Questions