Nullable types apply to structs. Objects already are able to assigned null values, therefore it doesnt make sense an object to be a valuable. That being said, Nullable<T> is equivalent to T?.
Eg:
Nullable num = null;
Nullable dateTime = null;
int? number= null;
DateTime? myBday = null;
Two read-only properties of Nullable are : HasValue , Value. HasValue property returns a boolean if the Nullable has a value otherwise returns false. Value read-only property accesses the value of the Type. There is also a method GetValueOrDefault, which returns the Value of the Type of returns the default value of the type.
A complementary operator to Nullable types is ??.
Conversions from a Nullable type to related type is possible, however might cause an exception.
int? num = null;
int num2 = (int)num; // this would cause an exception cause num is null.
For comparison operators <,>,== etc., nullable types can not be compared with a type that has a value.
int? num= null;
int num2 = 10;
if(num<num2) // you cant compare a value with null hence returns false.
{
}
?? operator comes to help if you need to evaluate a value with null and assign something to it:
eg:
int? num = null;
int result = num ?? 100;
This mean, if num is null then assing 100 to the variable.
You can also chain ?? operator as follows :
int num = null ?? null ?? 1;
Boxing and UnBoxing is possible for Nullable Types as follows :
int? num = null;
object o = num; // boxing
int? newNum = (int?) o; //unboxing
bool? bl = null; // this is possible, a boolean variable can be true, false and null.
object? ob = bl; // boxing, now ob object is null
bool? newbl = (bool?)ob; // unboxing, newbl is assigned to null
// Best practice to cast a bool? to bool is as follows :
bool? b = null;
if(b.HasValue)
{
// use b.Value
}
else
{
// b doenst have a value, ie: null.
}