Which 1 to use, ?? or GetValueOrDefault()

by Jacobus Meintjes September 18, 2009 10:59

After reading the article on DasCode.Net about the ?? operator, I gave my opinion and made the point that you should rather use GetValueOrDefault(). With that said I started playing around with a simple application, 2 variances using each one of these syntaxes.

To use ?? or GetValueOrDefault you have to declare a Nullable type variable e.g int? x = null;

?? is known as the null-coalescing operator and is used to define a default value for nullable value types as well as reference types. It returns the left-hand operand if it is not null; otherwise it returns the right operand. As explained on MSDN.

Application 1:

   1:  //you have to declare a nullable type
   2:  int? x = null;
   3:   
   4:  int y = x ?? 0;
   5:   
   6:  //you have to add brackets around x ?? 0,
   7:  //because it is converted to a conditional operator
   8:  if ((x ?? 0) == 0)
   9:  {
  10:        Console.WriteLine("x is zero(0).");
  11:  }

Reflector 1:

   1:  private static void Main(string[] args)
   2:  {
   3:      int? x = null;
   4:      int? CS$0$0000 = x;
   5:      int y = CS$0$0000.HasValue ? CS$0$0000.GetValueOrDefault() : 0;
   6:      CS$0$0000 = x;
   7:      if ((CS$0$0000.HasValue ? CS$0$0000.GetValueOrDefault() : 0) == 0)
   8:      {
   9:          Console.WriteLine("x is zero(0).");
  10:      }
  11:  }

Line 4 of Application 1 - is using int y = x ?? 0;. In reflector this code is changed to a conditional operator using the HasValue (property) and GetValueOrDefault() (method) from the Nullable class.

Line 8 of Application 1 - is using if ((x ?? 0) == 0) which in turn is also changed to a conditional operator, showing why you need to add the brackets around x ?? 0.

 

GetValueOrDefault retrieves the value of the current Nullable<(Of <(T>)>) object, or a default value, again on MSDN.

Application 2:

   1:  int? x = null;
   2:   
   3:  int y = x.GetValueOrDefault();
   4:   
   5:  if (x.GetValueOrDefault(-1) == 0)
   6:  {
   7:         Console.WriteLine("x is zero(0).");
   8:  }

 

Reflector 2:

   1:  int? x = null;
   2:  int y = x.GetValueOrDefault();
   3:  if (x.GetValueOrDefault(-1) == 0)
   4:  {
   5:       Console.WriteLine("x is zero(0).");
   6:  }

Application 2 and Reflector 2, both return the same result. Delving deeper into the code and examining the Nullable<T> class, you will find, 2 GetValueOrDefault overloaded methods. One method accepts no parameters, while the other accepts 1, T defaultValue. On line 3 and 5 of Application 2, you can see the differences between them.

GetValueOrDefault():

The value of the Value property if the HasValue property is true; otherwise, the default value of the current Nullable<> object. The type of the default value is the type argument of the current Nullable<> object, and the value of the default value consists solely of binary zeroes.

E.g int has a default value of 0 (zero) and, float has a default value of 0.0.

   1:  public T GetValueOrDefault()
   2:  {
   3:      return this.value;
   4:  }

GetValueOrDefault(-1):

Retrieves the value of the current Nullable<> object, or the specified default value.

Parameters
   defaultValue
           A value to return if the HasValue property is false.

Return Value
   The value of the Value property if the HasValue property is true; otherwise, the defaultValue parameter.

   1:  public T GetValueOrDefault(T defaultValue)
   2:  {
   3:      if (!this.HasValue)
   4:      {
   5:          return defaultValue;
   6:      }
   7:      return this.value;
   8:  }

 

Using any of these will give the same result, but for code reading purposes using GetValueOrDefault with or without parameters will be the better option.

Tags:

C#

Comments are closed

Powered by BlogEngine.NET 1.6.0.0
Theme by Mads Kristensen | Modified by Mooglegiant

About Me

Jacobus Meintjes
 
C# developer working with ASP.Net and/or Windows Forms.
Email Me

Cumulus

This will be shown to users with no Flash or Javascript.

Widget Twitter not found.

Root element is missing.X