Working with Nullable Types
Working
with value types and data can sometimes be challenging because a value type
doesn't normally hold a null value. This lesson show you how to overcome this
limitation with C# nullable types. Here's what you'll learn.
- Understand the problem that
nullable types solve
- See how to declare a nullable
type
- Learn how to use nullable types
Understanding the Problem with Value Types
and Null Values
As
explained in Lesson 12: Structs,
the default value of a struct (value type) is some form of 0. This is another
difference between reference types and value types, in addition to what was
described in Lesson 22: Topics on
C# Type. The default value of a reference type is null. If you're just writing C# code
and managing your own data source, such as a file that holds data for your
application, the default values for structs works fine.
In
reality, most applications work with databases, which have their own type
systems. The implications of working with database type systems is that you don't
have a one-to-one mapping between C# and database types. One glaring difference
is that database types can be set to null.
A database has no knowledge of reference and value types, which are C# language
(.NET Platform) concepts. This means that C# value type equivalents in the
database, such as int, decimal, and DateTime, can be set to null.
Since
a type in the database can be null,
but your C# value type can't be null,
you have to find some way to provide a translation in your C# code to account
for null values. Effectively, the
scheme you use will often be inconsistent from one program to another;
something you often don't have a choice about. For example, what if you wanted
to handle a null DateTime from SQL Server as the minimum DateTime value in C#. After that
project, your next task would be to read data from a legacy Foxpro database,
whose minimum DateTime value is
different from SQL Server. Because of this lack of constency and potential
confusion, C# 2.0 added nullable types, which are more elegant and natural for
working with null data.
Declaring Nullable Types
To
declare a value type as nullable, append a question mark, ?, to the type name. Here's how to declare
a DateTime variable as a nullable
type:
DateTime? startDate;
A
DateTime can't normally hold a null value, but the declaration above
enables startDate to hold null, as well as any legal DateTime value. The proper terminology is
to refer to the type of startDate
as a nullable DateTime.
You
can assign a normal value to startDate
like this:
startDate = DateTime.Now;
or
you can assign null, like
this:
startDate = null;
Here's
another example that declares and initializes a nullable int:
int? unitsInStock = 5;
The
unitsInStock in the example above
can be assigned a value of null
also.
Working with Nullable Types
When
you have nullable types, you'll want to check them to see if they're null. Here's an example that shows how you
can check for a null value:
bool
isNull = startDate == null;
Console.WriteLine("isNull: " + isNull);
The
example above shows that you only need to use the equals operator to check for null. You could also make the equality
check as part of an if statement,
like this:
int
availableUnits;
if
(unitsInStock == null)
{
availableUnits = 0;
}
else
{
availableUnits = (int)unitsInStock;
}
Note:
Notice the cast operator in the else clause above. An explicit conversion
is required when assigning from nullable to non-nullable types.
That's
several lines of code for something that appears to be such a common operation.
Fortunately, there's a better way to perform the same task, using the coalesce
operator, ??, shown below:
int
availableUnits = unitsInStock ?? 0;
The
coalesce operator works like this: if the first value (left hand side) is null, then C# evaluates the second
expression (right hand side).
Summary
This
lesson explained how nullable types can be useful in your C# applications -
especially when working with values from a database. You learned how to
declare a nullable type and how to assign values, both null and non-null to nullable types. Another skill you learned was
how to use nullable types by checking to see if their values are null. As you saw, the coalesce operator
can be useful to help work with nullable type variables when you need to assign
a valid value to a non-nullable type.
No comments :
Post a Comment