Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

null coalescing order of operation

I'm getting strange results from this method:

public static double YFromDepth(double Depth, double? StartDepth, double? PrintScale)
{               
    return (Depth - StartDepth ?? Globals.StartDepth) * PrintScale ?? Constants.YPixelsPerUnit ;
}

When I pass a null into StartDepth, the coalescing is failing because "Depth - StartDepth" is being evaluated seeming by first converting StartDepth to a default of 0 (downgraded?) instead of first looking at whether it is null and substituting in the Globals.StartDepth instead.

Is this a known thing? I was able to make this work by adding parenthesis, but I really didnt expect things to work this way.

like image 512
Brady Moritz Avatar asked Dec 16 '22 13:12

Brady Moritz


1 Answers

No, it's not a bug. It's the specified order of precedence - the binary - operator has higher precedence than ??, so your code is effectively:

return ((Depth - StartDepth) ?? Globals.StartDepth) * 
          PrintScale ?? Constants.YPixelsPerUnit;

If you don't want that precedence, you should specify it explicitly:

return (Depth - (StartDepth ?? Globals.StartDepth)) * 
          PrintScale ?? Constants.YPixelsPerUnit;

Personally I would expand the method to make it clearer:

double actualStartDepth = StartDepth ?? Globals.StartDepth;
double actualScale = PrintScale ?? Constants.YPixelsPerUnit;
return (depth - actualStartDepth) * actualScale;
like image 139
Jon Skeet Avatar answered Jan 05 '23 12:01

Jon Skeet