Top Tips Subject: | Nullable Numeric Datatypes |
Difficulty: | Beginner |
Summary: | Since the .NET Framework 2.0 (Visual Studio 2005 series) there is a new feature for numeric value types in C# and Visual Basic. You can now declare a value type and have it assigned null or Nothing. This article will explore the nullable value types and show you how to use them. |
Before the .NET framework 2.0 you could run into trouble by accidentally assigning a
null value (
Nothing in Visual Basic) to a value type. For example, a database field could return
DbNull when you expect an integer. Microsoft has tried to solve this issue by introducing nullable value types. Let me illustrate shortly what the difference between value types and reference types is:
A value type is a built-in type that occupies an address in memory and stores its value with it. A value type is a fixed length variable that always takes a certain amount of space to be stored. For example, an
int or
Integer (
System.Int32) in the .NET Framework is a 32-bit integer value, therefore using 4 bytes to store its value.
C#:
int a = 8; int b = a; b = 4; Console.Write(a);
|
This code will print the value
8. Integers
a and
b are value types, so when we say
'int b = a' that does not mean that they are the same object in memory, it means that the value should be copied from
a to
b.
A reference type on the other hand is a type that is stored somewhere in memory and contains a pointer to a value. This means that the value is not stored with the variable itself. The reference type has no fixed length and can point to an object that may vary in size during the course of the execution of your code. Any class you create and instantiate is a reference type. This is also why multiple variables in your code can represent the same object in memory; they point to the same object.
C#:
System.IO.FileInfo fInfo = new System.IO.FileInfo("c:\\test.txt"); System.IO.FileInfo fInfo2 = fInfo; Console.Write(fInfo2.FullName);
|
This code will print
"c:\test.txt". The line
'System.IO.FileInfo fInfo2 = fInfo;' sets
fInfo2 to point to the same object as
fInfo. Any changes in the object will be reflected in both variables, even though they are stored in different memory locations themselves.
When an object is
null or
Nothing, it simply means that the pointer of that object does not point anywhere. There is no reference to refer to. Since a value type stores its own value, it could never represent
null or
Nothing. That is changed now. You can declare a value type nullable and assign
null or
Nothing to it:
C#:
VB:
Dim myInt As Nullable(Of Integer);
|
Microsoft has taken this a bit further for C# where you can use the
? type modifier to indicate a nullable value type:
C#:
The downside of using nullable value types is that you must be careful using them along with non-nullable value types. For example, the next code will fail if the value of
x is
null:
C#:
public int DoSomething(int? x) { int y = (int)x; y++; return (y); }
|
VB:
Public Function DoSomething(ByVal x As Nullable(Of Integer)) As Integer Dim y As Integer = CType(x, Integer) Return y + 1 End Function
|
If
x in the above function is passed with the value
null or
Nothing, then
y cannot be assigned to it and a
InvalidOperationException will be thrown. You can prevent this from happening by first checking if
x is
null or
Nothing by using the
HasValue property of a nullable value type:
C#:
public int DoSomething(int? x) { int y;
if (x.HasValue) { y = (int)x; } else { y = 0; } y++;
return (y); }
|
VB:
Public Function DoSomething(ByVal x As Nullable(Of Integer)) As Integer Dim y As Integer
If x.HasValue Then y = CType(x, Integer) Else y = 0 End If
Return y + 1 End Function
|
Again, in C# Microsoft made it easier by also introducing a new operator
??. You can rewrite the aboce C# code as:
public int DoSomething(int? x) { int y = (x ?? 0); y++; return (y); }
|
The
?? operator first checks if
x is
null and if it is, it assigns the value
0 to
y. If
x is not
null then the value of
x is automatically cast to the type of
y and its value copied. Unfortunately none of these extra features are present in VB .NET 2005.
Some things you have to keep in mind using nullable value types:
- Take precaution when mixing them with non-nullable types.
- A nullable value type that is declared without a value will have the default value of null or Nothing.
- If you operate on two nullable value types and one of the values is null, then the result will always be null. For example, adding two int? values by using the + operator will always result in null when one of the values is null.
- When comparing two nullable types, the result will be a regular bool or Boolean, not a nullable bool or Boolean like in SQL.
This concludes this issue of Top Tips, I hope you found it helpful.