Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to access nullable values in c#

In our C# code, we already test if a variable is null before attempting to access it.

if (myInt.HasValue) {
  var yourInt = myInt;

  // do something with yourInt
}

My question: is there a difference in using the nullable property as if it wasn't after it has been tested versus the following?

if (myInt.HasValue) {
  var yourInt = myInt.Value; // see the difference?

  // do something with yourInt
}

Is this just a matter of preference or is there a distinct reason or performance impact for using .Value even after the nullable object has passed that test?

UPDATE

I expanded on my second example, we already test with HasValue, but there we use .Value to access the value.

UPDATE 2

I updated the examples to use vars because in our code we don't actually use int types, sorry about the poor example. In our code, we actually just use the object inside an NHibernate Criteria query - Expression.Eq("thing", myInt) query.

This doesn't throw a compilation error. I was trying to simplify the example to get to the root of my question without getting NHibernate involved. Sorry if this invalidates some of the answers. I was just trying to see if there is a hit on performance if we force another method to find the value versus explicitly calling .Value.

like image 908
shanabus Avatar asked May 02 '12 14:05

shanabus


People also ask

How do you access the underlying value of a nullable type?

If you want to use the default value of the underlying value type in place of null , use the Nullable<T>. GetValueOrDefault() method. At run time, if the value of a nullable value type is null , the explicit cast throws an InvalidOperationException.

Does HasValue check for null?

The HasValue property returns true if the variable contains a value, or false if it is null. You can only use == and != operators with a nullable type. For other comparison use the Nullable static class.

How do you handle nullable values in C#?

Empty(A constant for empty strings). This method will take a parameter that will be of System. String type. The method will return a Boolean value, like n case if the argument String type has null or empty string (“”), then it will return True value else it will return False value.

In which way do we declare nullable variable?

When you declare a variable with a nullable value type, its HasValue property has a default value of False . This means that by default the variable has no defined value, instead of the default value of its underlying value type.


1 Answers

UPDATE: This question was the subject of my blog on December 20th, 2012. I'll be following it up with more thoughts on this optimization later in December and early January 2013. Thanks for the great question!


I was just trying to see if there is a hit on performance if we force another method to find the value versus explicitly calling .Value

First off, if you have a performance question then you are the only person who can answer the question, and you answer it by trying it both ways with a stopwatch and seeing which one is faster. It is a mystery to me why people ask this question on StackOverflow so often. It is exactly like saying "Hey internet, here are pictures of two horses. Which one runs faster?" How should we know? Race them, and then you'll know. They're your horses.

Second, you are asking the wrong question in a general sense. The question should not be "is there a hit on performance?", but rather "is there an unacceptable hit on performance?" And again, we do not know what is or is not acceptable to you.

Third, you are asking the wrong question in a very specific sense. The correct question to ask here, if you are interested in nano-scale optimization, is which is faster, using the Value getter or the GetValueOrDefault method?

The answer is that typically the GetValueOrDefault method is faster than Value. Why? Because the difference is the difference between:

if (this.HasValue) return this.value; else throw new Exception();

and

return this.value; 

What's the difference there? The jitter will likely not inline the former method and therefore you are paying a penalty of up to several nanoseconds to make the extra call indirection.

If a penalty of several nanoseconds is relevant to you then (1) congratulations for writing a program that runs in only a few microseconds, and (2) you are going to need to measure extraordinarily carefully to see if there is any real difference, because nanoseconds are pretty darn small.

like image 70
Eric Lippert Avatar answered Oct 24 '22 21:10

Eric Lippert