# Friday, August 18, 2006
« Windows Live Writer | Main | Always show solution in visual studio 20... »

I've written already some articles in the past about the null coalescing operator (1) but recently my colleague found some "strange" behavior when using this operator. First of all the guilty code:

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Text;

    4 

    5 namespace ConsoleApplicationNullableTypes

    6 {

    7     public class NullCoalescingTestWithinObject

    8     {

    9         static void Main(string[] args)

   10         {

   11             int multiplicator = 5;

   12             int workRegime = 6;

   13 

   14             SomeObject so = new SomeObject();

   15             so.Test = 7;

   16 

   17             decimal result = (so.Test ?? 0 * multiplicator) / workRegime;

   18 

   19             Console.WriteLine(result.ToString("N"));

   20 

   21             Console.ReadLine();

   22         }

   23     }

   24 

   25     internal class SomeObject

   26     {

   27         private decimal? _test;

   28 

   29         public decimal? Test

   30         {

   31             get { return _test; }

   32             set { _test = value; }

   33         }

   34     }

   35 }

 The actual behavior for investigation is on line 17. The parenthesis are omitted around the statement so.Test ?? 0. This causes the following code to be produced (I used Lutz Roeder's .NET Reflector tool for this):

private static void Main(string[] args)
{
      int num2 = 6;
      SomeObject obj1 = new SomeObject();
      obj1.Test = new Nullable<decimal>(new decimal(7));
      Nullable<decimal> nullable1 = obj1.Test;
      Console.WriteLine(((nullable1.HasValue ? nullable1.GetValueOrDefault() : new decimal(0)) / ((decimal) num2)).ToString("N"));
      Console.ReadLine();
}

The output is 1.17 and not really what one would expect.

Now with the parenthesis placed around the statement so.Test ?? 0 so line 17 becomes:

   17 decimal result = ((so.Test ?? 0) * multiplicator) / workRegime;

The output becomes 5.83 and is what is expected. Now the following code is generated:

private static void Main(string[] args)
{
      int num1 = 5;
      int num2 = 6;
      SomeObject obj1 = new SomeObject();
      obj1.Test = new Nullable<decimal>(new decimal(7));
      Nullable<decimal> nullable1 = obj1.Test;
      Console.WriteLine((((nullable1.HasValue ? nullable1.GetValueOrDefault() : new decimal(0)) * ((decimal) num1)) / ((decimal) num2)).ToString("N"));
      Console.ReadLine();
}

For developers whom are still new to this new operator you must be aware of the operator precedence in C#(2). The * operator is normally executed before the ?? operator. But in the generated code we can clearly see that the num1 variable, in our code multiplicator, is omitted which causes some strange side effects to your code to kick in.

Grz, Kris.

(1): Testing upon Nullable types in C# 2.0 and Be sure to put in some default value when testing with Nullable types in .NET 2.0.
(2): operator precedence in C#

kick it on DotNetKicks.com