Search code examples
c#null-coalescing-operator

What is the sequence of this inline null check and addition evaluation


I can't think of a better title, but this bug took me ages to find.

Can someone explain to me why this is giving me different outputs?

string may = "May";
string june = "June";
string july = "July";
Console.WriteLine(may?.Length ?? 0  + june?.Length ?? 0 + july?.Length ?? 0) ;
Console.WriteLine(may == null ? 0 : may.Length  + june == null ? 0 : june.Length + july == null ? 0 : july.Length) ;
Console.WriteLine( (may == null ? 0 : may.Length)  + (june == null ? 0 : june.Length) + (july == null ? 0 : july.Length)) ;

I have stepped through it and in my head I just can't figure out what the hell is going on. What's the sequence of evaluation here?

I would expect the string null coalescing logic or ternary logic to be like so (which works btw!):

int tempRes = 0;

tempRes+=may == null ? 0 : may.Length;
tempRes+=june == null ? 0 : june.Length;
tempRes+=july == null ? 0 : july.Length;

Console.WriteLine(tempRes);

Solution

  • It's not so much sequence of evaluation as it is operator precedence.

    may?.Length ?? 0  + june?.Length ?? 0 + july?.Length ?? 0
    

    This means:

    may?.Length ?? (0  + june?.Length) ?? (0 + july?.Length) ?? 0
    

    which is clearly not what you want. What you want can be expressed as

    (may?.Length ?? 0) + (june?.Length ?? 0) + (july?.Length ?? 0)
    

    Likewise,

    may == null ? 0 : may.Length  + june == null ? 0 : june.Length + july == null ? 0 : july.Length
    

    means

    may == null ? 0 : ((may.Length  + june) == null ? 0 : ((june.Length + july) == null ? 0 : july.Length))