Can be empty type, type
The three beautiful features of the void type, anonymous method, and iterator are proposed in C #2.0.
1. Empty type
When using the database, we will find a conflict: the database Field settings allow null, such as the date field, when you want to map a database table to an object in C #, you will find that the DateTime type cannot be null in C!
1.1 Introduction
It can be null or a value type, but it is a value type that contains null values: int? Nullable = null;
Int? It is an int type that can be empty. Obviously, this is another syntactic sugar, so there is certainly no int? This type. For the compiler, int? It will be compiled into the Nullable <int> type to empty the type.
The null types provided in C #2.0 are Nullable <T> and Nullable (This T is a generic parameter ). In C #, it is defined as public struct Nullable <T> where T: struct. Obviously, the generic type can only be a value type. The following code demonstrates how to use an empty type:
1 static void Main (string [] args) 2 3 {4 Nullable <int> value = 1; // int? Value = 1 can also be 5 Console. writeLine ("outputs with null values:"); 6 Display (value); 7 Console. writeLine (); 8 9 value = new Nullable <int> (); 10 Console. writeLine ("outputs with null type and no value:"); 11 Display (value); 12 Console. readKey (); 13 14} 15 16 private static void Display (int? Value) 17 {18 Console. writeLine ("null type value: {0}", value. hasValue); 19 if (value. hasValue) 20 {21 Console. writeLine ("value: {0}", value. value); 22} 23 // if there is a Value of the null type, the Value of the Value attribute is returned. Otherwise, the default Value 24 Console is returned. writeLine ("GetValueorDefault (): {0}", value. getValueOrDefault (); 25 // if there is a Value of the null type, the Value of the Value attribute is returned; otherwise, the 226 Console is returned. writeLine ("GetValueorDefault (): {0}", value. getValueOrDefault (2); 27 // If the HasValue attribute is true, the Value Attribute returns the hash code of the object; otherwise, it is the 028 Console. writeLine ("use of GetHashCode () method: {0}", value. getHashCode (); 29}
1.2 null merge Operator
That is, question mark ?? Operator, which determines the Left and Right operands. If the number on the left is not null, the number on the left is returned. If the number on the left is null, the number on the right is returned. This operator can be used for null or reference types, but not for value types. For example:
1 string stringnotnull="123"2 string stringisnull=null;3 string result=stringnotnull ?? "456";4 string result=stringisnull ?? "12";
The running result of the above Code is: result = "123"; result2 = "12 ".
1.3 empty packing and unpacking
Since there is a packing and unpacking process for the value type, and the empty type belongs to the value type, there will naturally be packing and unpacking operations, next, let's take a look at the process of packing and disassembling empty types.
When an empty type is assigned to the referenced type variable, CLR will pack the Nullable object. CLR first checks whether the null type is null. If there is null, CLR will not perform the actual packing operation (because null can be directly assigned to a reference type variable); if it is not null, CLR obtains the value from an empty type object and boxed the value (that is, the packing process of the value type ).
When a boxed value type is assigned to a variable of the empty type, CLR unpacks the value type. If the reference of the boxed value type is null, the CLR also sets the null type to null.
1 static void Main (string [] args) 2 {3 Console. writeLine ("Empty packing and unpacking are used as follows:"); 4 BoxAndUnbox (); 5 Console. readKey (); 6} 7 8 private static void BoxAndUnbox () 9 {10 Nullable <int> nullable = 5; 11 int? Nullablewithoutvalue = null; 12 Console. writeLine ("read non-null type can be null type is {0}", nullable. getType (); 13 // exception with NullReferenceException 14 // Console. writeLine ("the null type to read is {0}", nullablewithoutvalue. getType (); 15 object obj = nullable; 16 Console. writeLine ("Get the boxed obj type: {0}", obj. getType (); 17 18 int value = (int) obj; 19 nullable = (int ?) Obj; 20 21 // bind an empty object with no value 22 obj = nullablewithoutvalue; 23 Console. writeLine ("whether obj is null: {0} After null can be boxed", obj = null ); 24 25 // The Unpacking must be empty type 26 nullable = (int ?) Obj; 27}
The running result is as follows:
The above results show that:
(1) When the GetType method is used to obtain the null type of the value assignment, the returned value is the value assignment type. In the previous code, it is System. int32, not System. nullable <System. int32> type.
(2) If you use the GetType function to obtain the reference type after packing for the null type that has been assigned a value, the output type will still be the value assignment type, in the previous code, it is System. int32.
(3) If a non-empty value type is packed and then unpacked, it cannot be split. Otherwise, an NullReferenceException is thrown. Because obj is equal to null when no value can be empty, that is, an empty address is referenced. If the unboxing is non-empty, it is equivalent to assigning null to an int type variable, the int type property value type cannot be assigned null. Therefore, an exception occurs.
(4) Note: Before calling the GetType function, the compiler will pack the null type to make it null, that is, null reference. Therefore, when you call the GetType function, an empty reference exception is thrown.