Bradley Jones
August 15, 2005
August 15, 2005
With the newest standard for the C# language, there is now support for nullable data types. This small change could be a huge help for those who deal with databases containing fields that are optional. Nullable data types can also be helpful in other situations as well.
Defining Nullable Types
int myInt = 1;
int? myNullableInt = 1;
double? myDouble = 3.14159; double? myOtherDouble = null;
Using a Nullable Type
int? nFirst = null; int Second = 2; nFirst = Second; // Valid nFirst = 123; // Valid Second = nFirst; // Also valid nFirst = null; // Valid Second = nFirst; // Exception, Second is nonnullable.
if (nFirst.HasValue) Second = nFirst;
Using Operators with Nullable Values: Lifted Operators
int ValA = 10; int? ValB = 3; int? ValC = ValA * ValB;
int ValA = 10; int? ValB = null; int? ValC = ValA * ValB;
int ValA = 10; int? ValB = 3; int ValC = ValA * ValB; // ValC not nullable
Comparisons
int abc = 123; int xyz = 890; int? def = null; int? uvw = 123; Comparison Result abc == xyz // false abc == def // false def == null // true abc == uvw // true uvw == null // false uvw != null // true
Comparison Result abc > uvw // false, they are equal abc < def // false, def is null uvw < def // false, because def is null def > null // false, because right side is null uvw > null // false, because right side is null
Removing Nullability
returnValue = first ?? second;
Note: returnValue can be either a nullable or non-nullable variable.
int? ValA= 123; int? ValB = null; int NewVarA = ValA ?? -1; int NewVarB = ValB ?? -1;
In Conclusion...
About the Author
Bradley Jones, CodeGuru Site Manager, is a Microsoft MVP that works for Jupitermedia as an Executive Editor over many of the software development sites and channels. His experience includes development in C, C++, VB, some Java, C#, ASP, COBOL, and more as well as having been a developer, consultant, analyst, lead, and much more. His recent books include Teach Yourself the C# Language in 21 Days.
Bradley Jones, CodeGuru Site Manager, is a Microsoft MVP that works for Jupitermedia as an Executive Editor over many of the software development sites and channels. His experience includes development in C, C++, VB, some Java, C#, ASP, COBOL, and more as well as having been a developer, consultant, analyst, lead, and much more. His recent books include Teach Yourself the C# Language in 21 Days.
Defining Nullable Types
Defining a nullable type is very similar to defining the equivalent non-nullable type. The difference is in the use of the ? type modifier. To define an integer, you normally would do a simple declaration:
int myInt = 1;
To make myInt able to store a null value, you would declare it as such:
int? myNullableInt = 1;
As you can see, these two variables look as though they are the same. The nullable version, however, is much different. The nullable version is actually a structure that combines a value type with a flag to indicate whether the value is null. Additionally, a nullable type has two publicly readable properties, HasValue and value. HasValue is a bool that is true if there is a value stored; otherwise, it is false if the variable is null. If HasValue is true, you can get the value of the variable. If it is false and you attempt to get the value, an exception will be thrown.
null is now a keyword for C#. Additionally, it can be assigned to a nullable variable. The following are two valid assignments for a nullable variable:
double? myDouble = 3.14159; double? myOtherDouble = null;
As you can see, myDouble is assigned a value, but could also be assigned null. In the second statement, myOtherDouble is initialized to contain a null value—something you can't do with a non-nullable type.
Using a Nullable Type
A nullable type can be used in the same way that a regular value type can be used. In fact, implicit conversions are built in for converting between a nullable and non-nullable variable of the same type. This means you can assign a standard integer to a nullable integer and vice versa:
int? nFirst = null; int Second = 2; nFirst = Second; // Valid nFirst = 123; // Valid Second = nFirst; // Also valid nFirst = null; // Valid Second = nFirst; // Exception, Second is nonnullable.
In looking at the above statements, you can see that a nullable and nonnullable variable can exchange values as long as the nullable variable does not contain a null. If it contains a null, an exception is thrown. To help avoid throwing an exception, you can use the nullable's HasValue property:
if (nFirst.HasValue) Second = nFirst;
As you can see, if nFirst has a value, the assignment will happen; otherwise, the assignment is skipped.
Using Operators with Nullable Values: Lifted Operators
In addition to the automatic conversions between a nullable and non-nullable variable of the same value type, there also are changes with the operators to allow them to work with nullable and non-nullable values. These operators are called
lifted operators.
Consider the following code:
int ValA = 10; int? ValB = 3; int? ValC = ValA * ValB;
What is stored in Val C? The value of 30 would be stored into ValC. The standard operators have been modified so that they "lift" the non-nullable values to being nullable, thus allowing the standard operations to work. Now, consider the following change:
int ValA = 10; int? ValB = null; int? ValC = ValA * ValB;
What would ValC contain this time? ValC would contain null. In the case where either operand is null, the result of a lifted operation also will be null. Even if you were doing addition or subtraction, it would still be null. So, ValA + ValB using the above values would result in null, not 10.
What if ValC were not a nullable type? What does the following do then?
int ValA = 10; int? ValB = 3; int ValC = ValA * ValB; // ValC not nullable
This code would actually throw an exception. The result of ValA * ValB is null and a null can't be assigned to a non-nullable type. As such, an exception is thrown.
Comparisons
Comparisons occur in a similar manner to the mathematical operations. The operands in a comparison are lifted to both being nullable. Then, the comparison is done. If one of the operands contains a null, the result of the comparison will be false.
int abc = 123; int xyz = 890; int? def = null; int? uvw = 123; Comparison Result abc == xyz // false abc == def // false def == null // true abc == uvw // true uvw == null // false uvw != null // true
Comparison Result abc > uvw // false, they are equal abc < def // false, def is null uvw < def // false, because def is null def > null // false, because right side is null uvw > null // false, because right side is null
Removing Nullability
returnValue = first ?? second;
Note: returnValue can be either a nullable or non-nullable variable.
int? ValA= 123; int? ValB = null; int NewVarA = ValA ?? -1; int NewVarB = ValB ?? -1;
In Conclusion...
About the Author
Bradley Jones, CodeGuru Site Manager, is a Microsoft MVP that works for Jupitermedia as an Executive Editor over many of the software development sites and channels. His experience includes development in C, C++, VB, some Java, C#, ASP, COBOL, and more as well as having been a developer, consultant, analyst, lead, and much more. His recent books include Teach Yourself the C# Language in 21 Days.
Bradley Jones, CodeGuru Site Manager, is a Microsoft MVP that works for Jupitermedia as an Executive Editor over many of the software development sites and channels. His experience includes development in C, C++, VB, some Java, C#, ASP, COBOL, and more as well as having been a developer, consultant, analyst, lead, and much more. His recent books include Teach Yourself the C# Language in 21 Days.
If comparing for equality (or non-equality), two variables containing null will be considered equal. A variable containing null compared to a variable with any value will be considered not equal. The following are some examples of comparisons:
int abc = 123; int xyz = 890; int? def = null; int? uvw = 123; Comparison Result abc == xyz // false abc == def // false def == null // true abc == uvw // true uvw == null // false uvw != null // true
In all comparisons, the result is a Boolean value of true or false. When doing relative comparisons, you also will get a returned Boolean value of true or false; however, a null value impacts things. In the case of relative comparisons, if either (or both) of the values is null, a value of false will be returned. The following are some examples of relative comparisons and their results. These use the same defined variables from above.
Comparison Result abc > uvw // false, they are equal abc < def // false, def is null uvw < def // false, because def is null def > null // false, because right side is null uvw > null // false, because right side is null
Removing Nullability
C# also gets an additional operator in its newest version. This is the ?? operator used for null coalescing. The null coalescing operator takes the following format:
returnValue = first ?? second;
In this case, if first is not null, its value will be returned to returnValue. If first is null, the value of second will be returned.
Note: returnValue can be either a nullable or non-nullable variable.
If you wanted to move a nullable varaible's value to a non-nullable version, you could do the following:
int? ValA= 123; int? ValB = null; int NewVarA = ValA ?? -1; int NewVarB = ValB ?? -1;
When the above is completed, NewVarA will contain the value of 123 because ValA was not null. NewVarB will contain the value of -1 because ValB was null. As you can see, this allows you to change variables with a null value to a defaulted value. In this case, the defaulted value is -1.
In Conclusion...
In conclusion, the newest version of C# allows for a nullable type. These types can be used with non-nullable types with little thought and little effort because the conversions will be built into the language. The nullable types should make working with database records and other optional information much easier going forward.
Nullable types is a part of the ECMA-334 version of C#. You'll need a compiler that supports this C# standard to use nullable types. Visual Studio 2005 supports this standard.
# # #
About the Author
Bradley Jones , CodeGuru Site Manager, is a Microsoft MVP that works for Jupitermedia as an Executive Editor over many of the software development sites and channels. His experience includes development in C, C++, VB, some Java, C#, ASP, COBOL, and more as well as having been a developer, consultant, analyst, lead, and much more. His recent books include Teach Yourself the C# Language in 21 Days.
Bradley Jones , CodeGuru Site Manager, is a Microsoft MVP that works for Jupitermedia as an Executive Editor over many of the software development sites and channels. His experience includes development in C, C++, VB, some Java, C#, ASP, COBOL, and more as well as having been a developer, consultant, analyst, lead, and much more. His recent books include Teach Yourself the C# Language in 21 Days.
Defining Nullable Types
Defining a nullable type is very similar to defining the equivalent non-nullable type. The difference is in the use of the ? type modifier. To define an integer, you normally would do a simple declaration:
int myInt = 1;
To make myInt able to store a null value, you would declare it as such:
int? myNullableInt = 1;
As you can see, these two variables look as though they are the same. The nullable version, however, is much different. The nullable version is actually a structure that combines a value type with a flag to indicate whether the value is null. Additionally, a nullable type has two publicly readable properties, HasValue and value. HasValue is a bool that is true if there is a value stored; otherwise, it is false if the variable is null. If HasValue is true, you can get the value of the variable. If it is false and you attempt to get the value, an exception will be thrown.
null is now a keyword for C#. Additionally, it can be assigned to a nullable variable. The following are two valid assignments for a nullable variable:
double? myDouble = 3.14159; double? myOtherDouble = null;
As you can see, myDouble is assigned a value, but could also be assigned null. In the second statement, myOtherDouble is initialized to contain a null value—something you can't do with a non-nullable type.
Using a Nullable Type
A nullable type can be used in the same way that a regular value type can be used. In fact, implicit conversions are built in for converting between a nullable and non-nullable variable of the same type. This means you can assign a standard integer to a nullable integer and vice versa:
int? nFirst = null; int Second = 2; nFirst = Second; // Valid nFirst = 123; // Valid Second = nFirst; // Also valid nFirst = null; // Valid Second = nFirst; // Exception, Second is nonnullable.
In looking at the above statements, you can see that a nullable and nonnullable variable can exchange values as long as the nullable variable does not contain a null. If it contains a null, an exception is thrown. To help avoid throwing an exception, you can use the nullable's HasValue property:
if (nFirst.HasValue) Second = nFirst;
As you can see, if nFirst has a value, the assignment will happen; otherwise, the assignment is skipped.
Using Operators with Nullable Values: Lifted Operators
In addition to the automatic conversions between a nullable and non-nullable variable of the same value type, there also are changes with the operators to allow them to work with nullable and non-nullable values. These operators are called
lifted operators.
Consider the following code:
int ValA = 10; int? ValB = 3; int? ValC = ValA * ValB;
What is stored in Val C? The value of 30 would be stored into ValC. The standard operators have been modified so that they "lift" the non-nullable values to being nullable, thus allowing the standard operations to work. Now, consider the following change:
int ValA = 10; int? ValB = null; int? ValC = ValA * ValB;
What would ValC contain this time? ValC would contain null. In the case where either operand is null, the result of a lifted operation also will be null. Even if you were doing addition or subtraction, it would still be null. So, ValA + ValB using the above values would result in null, not 10.
What if ValC were not a nullable type? What does the following do then?
int ValA = 10; int? ValB = 3; int ValC = ValA * ValB; // ValC not nullable
This code would actually throw an exception. The result of ValA * ValB is null and a null can't be assigned to a non-nullable type. As such, an exception is thrown.
Comparisons
Comparisons occur in a similar manner to the mathematical operations. The operands in a comparison are lifted to both being nullable. Then, the comparison is done. If one of the operands contains a null, the result of the comparison will be false.
int abc = 123; int xyz = 890; int? def = null; int? uvw = 123; Comparison Result abc == xyz // false abc == def // false def == null // true abc == uvw // true uvw == null // false uvw != null // true
Comparison Result abc > uvw // false, they are equal abc < def // false, def is null uvw < def // false, because def is null def > null // false, because right side is null uvw > null // false, because right side is null
Removing Nullability
returnValue = first ?? second;
Note: returnValue can be either a nullable or non-nullable variable.
int? ValA= 123; int? ValB = null; int NewVarA = ValA ?? -1; int NewVarB = ValB ?? -1;
In Conclusion...
About the Author
Bradley Jones, CodeGuru Site Manager, is a Microsoft MVP that works for Jupitermedia as an Executive Editor over many of the software development sites and channels. His experience includes development in C, C++, VB, some Java, C#, ASP, COBOL, and more as well as having been a developer, consultant, analyst, lead, and much more. His recent books include Teach Yourself the C# Language in 21 Days.
Bradley Jones, CodeGuru Site Manager, is a Microsoft MVP that works for Jupitermedia as an Executive Editor over many of the software development sites and channels. His experience includes development in C, C++, VB, some Java, C#, ASP, COBOL, and more as well as having been a developer, consultant, analyst, lead, and much more. His recent books include Teach Yourself the C# Language in 21 Days.
If comparing for equality (or non-equality), two variables containing null will be considered equal. A variable containing null compared to a variable with any value will be considered not equal. The following are some examples of comparisons:
int abc = 123; int xyz = 890; int? def = null; int? uvw = 123; Comparison Result abc == xyz // false abc == def // false def == null // true abc == uvw // true uvw == null // false uvw != null // true
In all comparisons, the result is a Boolean value of true or false. When doing relative comparisons, you also will get a returned Boolean value of true or false; however, a null value impacts things. In the case of relative comparisons, if either (or both) of the values is null, a value of false will be returned. The following are some examples of relative comparisons and their results. These use the same defined variables from above.
Comparison Result abc > uvw // false, they are equal abc < def // false, def is null uvw < def // false, because def is null def > null // false, because right side is null uvw > null // false, because right side is null
Removing Nullability
C# also gets an additional operator in its newest version. This is the ?? operator used for null coalescing. The null coalescing operator takes the following format:
returnValue = first ?? second;
In this case, if first is not null, its value will be returned to returnValue. If first is null, the value of second will be returned.
Note: returnValue can be either a nullable or non-nullable variable.
If you wanted to move a nullable varaible's value to a non-nullable version, you could do the following:
int? ValA= 123; int? ValB = null; int NewVarA = ValA ?? -1; int NewVarB = ValB ?? -1;
When the above is completed, NewVarA will contain the value of 123 because ValA was not null. NewVarB will contain the value of -1 because ValB was null. As you can see, this allows you to change variables with a null value to a defaulted value. In this case, the defaulted value is -1.
In Conclusion...
In conclusion, the newest version of C# allows for a nullable type. These types can be used with non-nullable types with little thought and little effort because the conversions will be built into the language. The nullable types should make working with database records and other optional information much easier going forward.
Nullable types is a part of the ECMA-334 version of C#. You'll need a compiler that supports this C# standard to use nullable types. Visual Studio 2005 supports this standard.
# # #
About the Author
Bradley Jones , CodeGuru Site Manager, is a Microsoft MVP that works for Jupitermedia as an Executive Editor over many of the software development sites and channels. His experience includes development in C, C++, VB, some Java, C#, ASP, COBOL, and more as well as having been a developer, consultant, analyst, lead, and much more. His recent books include Teach Yourself the C# Language in 21 Days.
Bradley Jones , CodeGuru Site Manager, is a Microsoft MVP that works for Jupitermedia as an Executive Editor over many of the software development sites and channels. His experience includes development in C, C++, VB, some Java, C#, ASP, COBOL, and more as well as having been a developer, consultant, analyst, lead, and much more. His recent books include Teach Yourself the C# Language in 21 Days.
If comparing for equality (or non-equality), two variables containing null will be considered equal. A variable containing null compared to a variable with any value will be considered not equal. The following are some examples of comparisons:
int abc = 123; int xyz = 890; int? def = null; int? uvw = 123; Comparison Result abc == xyz // false abc == def // false def == null // true abc == uvw // true uvw == null // false uvw != null // true
In all comparisons, the result is a Boolean value of true or false. When doing relative comparisons, you also will get a returned Boolean value of true or false; however, a null value impacts things. In the case of relative comparisons, if either (or both) of the values is null, a value of false will be returned. The following are some examples of relative comparisons and their results. These use the same defined variables from above.
Comparison Result abc > uvw // false, they are equal abc < def // false, def is null uvw < def // false, because def is null def > null // false, because right side is null uvw > null // false, because right side is null
Removing Nullability
C# also gets an additional operator in its newest version. This is the ?? operator used for null coalescing. The null coalescing operator takes the following format:
returnValue = first ?? second;
In this case, if first is not null, its value will be returned to returnValue. If first is null, the value of second will be returned.
Note: returnValue can be either a nullable or non-nullable variable.
If you wanted to move a nullable varaible's value to a non-nullable version, you could do the following:
int? ValA= 123; int? ValB = null; int NewVarA = ValA ?? -1; int NewVarB = ValB ?? -1;
When the above is completed, NewVarA will contain the value of 123 because ValA was not null. NewVarB will contain the value of -1 because ValB was null. As you can see, this allows you to change variables with a null value to a defaulted value. In this case, the defaulted value is -1.
In Conclusion...
In conclusion, the newest version of C# allows for a nullable type. These types can be used with non-nullable types with little thought and little effort because the conversions will be built into the language. The nullable types should make working with database records and other optional information much easier going forward.
Nullable types is a part of the ECMA-334 version of C#. You'll need a compiler that supports this C# standard to use nullable types. Visual Studio 2005 supports this standard.
# # #
About the Author
Bradley Jones , CodeGuru Site Manager, is a Microsoft MVP that works for Jupitermedia as an Executive Editor over many of the software development sites and channels. His experience includes development in C, C++, VB, some Java, C#, ASP, COBOL, and more as well as having been a developer, consultant, analyst, lead, and much more. His recent books include Teach Yourself the C# Language in 21 Days.
Bradley Jones , CodeGuru Site Manager, is a Microsoft MVP that works for Jupitermedia as an Executive Editor over many of the software development sites and channels. His experience includes development in C, C++, VB, some Java, C#, ASP, COBOL, and more as well as having been a developer, consultant, analyst, lead, and much more. His recent books include Teach Yourself the C# Language in 21 Days.