In this specific case it is a syntactic sugar to indicate a cancellable type. This means that your DateTime
which would not normally accept a null value, may accept.
This is especially useful for use with database fields that usually accept null. But it can be used for anything.
Note that in type by value the default is something that represents a zero (whatever value is suitable to represent this), in general represented by the constant MinValue
. When the guy is voidable, the default of it is the same of the types by reference, so it happens to be a null
.
It is only interesting to have this feature in the language for types by value. Reference types accept nulls by default.
The voidable type is a simple structure with basically two members. One is the value and obviously is of the main type and the other is a Boolean indicator whether it is null or not. Obviously if it is null, the value will not be available. This is necessary because no value of a type by value is invalid, it needs a given helper. Obviously there is a small overhead from memory.
The semantics remains the type by value, but some small discrepancies can be observed in some very specific situations.
Every type by value can be implicitly converted to its annulable equivalent (note that the types are different). The opposite is not true
If you are interested in understanding how it works, you have the class source Nullable
.
In his example is without syntactic sugar would look like this:
public Nullable<DateTime> BirthDate { get; set; }
Behold working in the ideone. And in the .NET Fiddle. Also put on the Github for future reference.
DateTime dt = DateTime.Now;
DateTime? dtn = null;
WriteLine(dt);
WriteLine(dtn);
dtn = dt;
WriteLine(dtn);
dt = dtn ?? default(DateTime); //daria erro de compilação se não fizesse esta verificação
WriteLine(dtn);
dt = dtn.GetValueOrDefault(); //também pode usar isto que faz a verificação internamente
WriteLine(dtn);
if (dtn != null) {
WriteLine("tem valor");
}
if (dtn.HasValue) { //dá o mesmo resultado e seu uso é dispensável
WriteLine("tem valor");
}
Note that direct use of properties HasValue
and Value
is not necessary and usually not recommended. These properties are available for the compiler and other tools to handle the type appropriately. Its use in "normal" code must be rare and must have a justification. The idea is that the type be used as if the null were native to it. Using them would make the use of the voidable type less transparent and decrease the resource’s syntactic sugar capacity.
Related: What is the meaning of the operator "??" and What is the operator "?."?
Did not know of the existence Nullable<type> thank you.
– PauloHDSousa