First, why it exists
When designing a database, you can define a column's data type as a 32-bit integer and map to the Int32 data type of the FCL. However, a column in the database may allow a value to be empty, that is, the column allows no value on a row. Processing database data with the. NET framework can become quite difficult because there is no way to represent a Int32 value as NULL in the CLR.
Second, what is it exactly?
To address this problem, Microsoft introduced the concept of a nullable value type in the CLR. To understand how they work, take a look at the system.nullable<t> structure and note that it is a value type.
1 [Serializable]2 Public structNullable<t>whereT:struct3 {4 Private BOOLHasValue;5 6 InternalT value;7 8 Public BOOLHasValue9 {Ten Get One { A return This. HasValue; - } - } the PublicT Value - { - Get - { + if(! This. HasValue) - { + Throw NewInvalidOperationException ("Nullable object must has a value."); A } at return This. Value; - } - } - - PublicNullable (T value) - { in This. Value =value; - This. HasValue =true; to } + - PublicT GetValueOrDefault () the { * return This. Value; $ }Panax Notoginseng PublicT GetValueOrDefault (t defaultvalue) - { the if(! This. HasValue) + { A returnDefaultValue; the } + return This. Value; - } $ Public Override BOOLEquals (ObjectOther ) $ { - if(! This. HasValue) - { the returnother = =NULL; - }Wuyi returnOther! =NULL&& This. Value. Equals (other); the } - Public Override intGetHashCode () Wu { - if(! This. HasValue) About { $ return 0; - } - return This. Value. GetHashCode (); - } A Public Override stringToString () + { the if(! This. HasValue) - { $ return ""; the } the return This. Value. ToString (); the } the Public static implicit operator T? (T value) - { in return new T? (value); the } the Public static explicit operator T (t? value) About { the return value. Value; the } the}
1. When you use nullable<int32> x = 5 o'clock, you actually call nullable's parameter constructor to initialize the value type.
2. When using nullable<int32> x = null, the nullable parameterless constructor is actually called to initialize the value type.
Third, C # support for nullable value types
C # allows the use of a question mark notation to declare and initialize a nullable value type, such as Int32? x = 5, equivalent to nullable<int32> x = new nullable<int32> (5);
1.c# allows developers to perform transformations and transitions on a nullable instance
Int32? A = 5;
By looking at IL, you actually get the value of the Value property and assign it to B. So if a is equal to NULL, the following line of code throws an exception.
Int32 B = (Int32) A;
By looking at IL, you actually call the GetValueOrDefault method to get the value, and then call the new Nullable<double> constructor to initialize the variable.
Double? c = A;
Iv. empty join operators for C #
"??", gets two operands, if the left operand is not empty, returns the value of the operand, otherwise returns the value of the right operand.
V. CLR special support for nullable value types
1. Packing of nullable value types
When the CLR is boxing a nullable value type, it checks whether it is empty, and if it is empty, the CLR does not make any boxing and returns a null value. If a nullable instance is not empty, the CLR takes the value out of the nullable instance and boxing it.
[CLR via C #] nullable value types