Description: Nullable & lt; T & gt; type. Description: nullable type.

Source: Internet
Author: User
Tags unpack

Description: Nullable <T> type, details: nullable type

Directory
I. Introduction
Ii. syntax and usage
Iii. type conversion and Operation
Iv. packing and unpacking
5. GetType () method
6. ToString () method
7. System. Nullable help class
8. Syntactic sugar

 

I. Introduction

As we all know, value type variables cannot be null, which is why they are called value types. However, in the actual development process, the value also needs to benull. For example:

Scenario 1: You can retrieve an integer data column that can be empty from a database table.nullThe value cannot be assigned to the Int32 type in C;

Scenario 2: You bind attributes to the UI, but some value-type fields are not required (for example, the date of death in personnel management );

Scenario 3: in Java,java.Util.DateIs a reference type, so you can set this type of fieldnull. However, in CLR,System.DateTimeIt is a value type, and the DateTime variable cannotnull. If an application written in Java needs to communicate the date/time to the Web Service Running on CLR, if the Java application sendsnull, CLR does not provide the corresponding type;

Scenario 4: When passing value types in a function, you can use the default value if the parameter value cannot be provided and you do not want to transfer it. But sometimes the default value is not the best choice, because the default value actually passes a default parameter value, and the logic needs special processing;

Scenario 5: When deserializing data from xml or json, the value of a value type attribute is missing from the data source, which is inconvenient to handle.

Of course, there are many similar situations in our daily work.

To get rid of these situations, Microsoft has added the concept of a null value type in CLR. To better understand this, let's take a look.System.Nullable<T>Type logical definition:

1 namespace System 2 {3 [Serializable] 4 public struct Nullable <T> where T: struct 5 {6 private bool hasValue; 7 internal T value; 8 9 public Nullable (T value) {10 this. value = value; 11 this. hasValue = true; 12} 13 14 public bool HasValue {15 get {16 return hasValue; 17} 18} 19 20 public T Value {21 get {22 if (! HasValue) {23 ThrowHelper. throwInvalidOperationException (ExceptionResource. invalidOperation_NoValue); 24} 25 return value; 26} 27} 28 29 public T GetValueOrDefault () {30 return value; 31} 32 33 public T GetValueOrDefault (T defaultValue) {34 return HasValue? Value: defaultValue; 35} 36 37 public override bool Equals (object other) {38 if (! HasValue) return other = null; 39 if (other = null) return false; 40 return value. equals (other); 41} 42 43 public override int GetHashCode () {44 return HasValue? Value. GetHashCode (): 0; 45} 46 47 public override string ToString () {48 return HasValue? Value. toString (): ""; 49} 50 51 public static implicit operator Nullable <T> (T value) {52 return new Nullable <T> (value ); 53} 54 55 public static explicit operator T (Nullable <T> value) {56 return value. value; 57} 58} 59}View Nullable Definitions

The preceding definitions can be summarized as follows:

  • The Nullable <T> type is also a value type;
  • The Nullable <T> type contains a Value Attribute used to represent the basic Value. It also includesBooleanType HasValue attribute is used to indicate whether the value isnull;
  • Nullable <T> is a lightweight value type. The memory size occupied by Nullable <T> type instances is equal to one value type and oneBooleanThe sum of memory used by the type;
  • The generic parameter T of Nullable <T> must be of the value type. You can only use the Nullable <T> type with the value type. You can also use the User-Defined value type.

 

Ii. syntax and usage

To use the Nullable <T> type, you only need to specify a generic parameter T for other value types.

Example:

1 Nullable <int> I = 1; 2 Nullable <int> j = null; 3 Nullable <int> k; // This is an error syntax and an error is reported during compilation.

CLR also provides a simplified method.

1     int? i = 1;2     int? j = null;

You can use the Value attribute to obtain the Value of the basic type. If notnullWill return the actual value, otherwise it will throwInvalidOperationExceptionException. You can check whether the Value attribute isnull.

1 Nullable <int> I = 1; 2 Nullable <int> j = null; 3 4 Console. writeLine (I. hasValue); 5 // output result: True 6 7 Console. writeLine (I. value); 8 // output result: 1 9 10 Console. writeLine (j. hasValue); 11 // output result: False12 13 Console. writeLine (j. value); 14 // throw an exception: System. invalidOperationException

 

Iii. type conversion and Operation

C # also supports Simple syntax to use the Nullable <T> type. It also supports implicit conversion and conversion of Nullable <T> instances. The following is an example:

1 // implicitly convert from System. Int32 to Nullable <Int32> 2 int? I = 5; 3 4 // implicitly convert from 'null' to Nullable <Int32> 5 int? J = null; 6 7 // The explicit conversion from Nullable <Int32> to Int32 is 8 int k = (int) I; 9 10 // the conversion between the base types is 11 Double? X = 5; // implicit conversion from Int to Nullable <Double> 12 Double? Y = j; // implicitly convert Nullable from Nullable <Int32> <Double>

Use the operator for the Nullable <T> type, which is the same as the basic type usage method.

  • Unary operator (++, --,-, etc.), if the Nullable <T> type value isnull, Returnnull;
  • Binary operators (+,-, *,/, %, ^, etc.) Any operand isnull, Returnnull;
  • For the = Operator, if both operands arenull, The expression is calculatedtrueIf any operand isnull, The expression is calculated as false. If neither of them isnull, Which is compared as usual.
  • For Relational operators (>, <, >=, <=), if any operand isnull, The calculation result isfalseIf none of the operands arenullTo compare the value.

See the following example:

1 int? I = 5; 2 int? J = null; 3 4 // unary operator 5 I ++; // I = 6 6 j =-j; // j = null 7 8 // binary operator 9 I = I + 3; // I = 9 10 j = j * 3; // j = null; 11 12 // equal sign operator (= ,! =) 13 var r = I = null; // r = false14 r = j = null; // r = true15 r = I! = J; // r = true16 17 // comparison operator (<,>, <=,> =) 18 r = I> j; // r = false19 20 I = null; 21 r = I> = j; // r = false. Note that I = null, j = null, but> = the returned result is false.

Nullable <T> can also support ternary operators like reference types.

1 // if the employee's age returns null (the birth date may not be entered), set the value 0. 2 int Age = employee. age ?? 0; 3 4 // use the ternary operator in an aggregate function. 5 int? [] Numbers ={}; 6 int total = numbers. Sum ()?? 0;

 

Iv. packing and unpacking

We already know that Nullable <T> is a value type. Now let's talk about its packing and unpacking.
CLR uses a special rule to handle Nullable <T> packing and unpacking. When an Nullable <T> type instance is boxed, CLR checks the HasValue attribute of the instance: If yestrue, Then the Value of the Instance Value attribute is boxed and the result is returned.falseDirectly returnnull.
In case of unpacking, it is different from the case in case of packing. The CLR checks whether the unpacking object isnullIf you create a new instance, new Nullable <T> (),null, The object is split into type T, and a new instance new Nullable <T> (t) is created ).

1 int? N = null; 2 object o = n; // No packing operation is performed. The null Value 3 4 Console is returned directly. writeLine ("o is null = {0}", object. referenceEquals (o, null); 5 // output: o is null = True 6 7 8 n = 5; 9 o = n; // o references a boxed Int3210 11 Console. writeLine ("o's type = {0}", o. getType (); 12 // output: o's type = System. int3213 14 o = 5; 15 16 // unpack Int32 type into Nullable <Int32> type 17 int? A = (Int32 ?) O; // a = 5 18 // unpack Int32 type into Int32 type 19 int B = (Int32) o; // B = 520 21 // create a file whose Initialization is null22 o = null; 23 // change null to Nullable <Int32> type 24 a = (Int32 ?) O; // a = null 25 B = (Int32) o; // throw an exception: NullReferenceException

 

5. GetType () method

When the Nullable <T> type is calledGetType()Method, the CLR actually returns the type of the generic parameter. Therefore, you may not be able to distinguish whether the Nullable <Int32> instance is of the Int32 or Nullable <Int32> type. See the following example:

1 int? I = 10; 2 Console. writeLine (I. getType (); 3 // The output result is: System. int324 5 I = null; 6 Console. writeLine (I. getType (); // NullReferenceException

Cause analysis:

This is becauseGetType()Method, the current instance has been boxed, according to the previous part of the packing and unpacking content, here actually calls the Int32 typeGetType()Method.

Of the call value typeGetType()You can verify this by yourself.

 

6. ToString () method

When the Nullable <T> type is calledToString()If the value of the HasValue attribute isfalse, ReturnsString.EmptyIf the value of this attribute istrue, The Calling logic isValue.ToString(). See the following example:

1 int? I = 10; 2 Console. writeLine (I. toString (); 3 // output: 104 5 I = null; 6 Console. writeLine (I. toString () = string. empty); 7 // output result: True

 

7. System. Nullable help class

Microsoft also providesSystem.NullableStatic class, including three methods:

1 public static class Nullable 2 {3 // return the specified basic type parameter of the null type. 4 public static Type GetUnderlyingType (Type nullableType); 5 6 // compare two relative values System. Nullable <T> object. 7 public static int Compare <T> (T? N1, T? N2) where T: struct 8 9 // indicates whether the two specified System. Nullable <T> objects are equal. 10 public static bool Equals <T> (T? N1, T? N2) where T: struct11}

Here we will focus onGetUnderlyingType(Type nullableType)The other two methods are used to compare values. You can study them yourself.

  GetUnderlyingType(Type nullableType)The method is used to return a basic type that can be empty. IfnullableTypeIf the parameter is not a closed Nullable <T> generic type, returnnull.

1 Console. writeLine (Nullable. getUnderlyingType (typeof (Nullable <int>); 2 // output result: System. int32 3 4 Console. writeLine (Nullable. getUnderlyingType (typeof (Nullable <>) = null); 5 // output result: True 6 7 Console. writeLine (Nullable. getUnderlyingType (typeof (int) = null); 8 // output: True 9 10 Console. writeLine (Nullable. getUnderlyingType (typeof (string) = null); 11 // output: True

8. Syntactic sugar

Microsoft provides a wide range of syntactic sugar for Nullable <T> to reduce the workload of developers. The following is my reference.

Shorthand Compiled statement
 1     int? i = 5; 2  3     int? j = null; 4  5     var r = i != null; 6  7     var v = (int) i; 8  9     i++;10 11     i = i + 3;12 13     r = i != j;14 15     r = i >= j;16 17     var k = i + j;18 19     double? x = 5;20     21     double? y = j;
 1     int? i = new int?(5); 2  3     int? j = new int?(); 4  5     var r = i.HasValue; 6  7     var v = i.Value; 8  9     i = i.HasValue ? new int?(i.GetValueOrDefault() + 1) : new int?();10 11     i = i.HasValue ? new int?(i.GetValueOrDefault() + 3) : new int?();12 13     r = i.GetValueOrDefault() != j.GetValueOrDefault() || i.HasValue != j.HasValue;14 15     r = i.GetValueOrDefault() >= j.GetValueOrDefault() && i.HasValue & j.HasValue;16 17     int? k = i.HasValue & j.HasValue ? new int?(i.GetValueOrDefault() + j.GetValueOrDefault()) : new int?();18 19     double? x = new double?((double) 5);20     21     double? y = j.HasValue ? new double?((double) j.GetValueOrDefault()) : new double?();
 

Refer:

  • Https://www.codeproject.com/Articles/11854/C-Nullable-Types
  • Https://www.codeproject.com/Articles/275471/Nullable-Types-in-Csharp-Net
  • Https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/nullable-types/using-nullable-types
  • Https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/nullable-types/index

 

Reprinted please indicate the source, original link: http://www.cnblogs.com/tdfblog/p/Nullable-Types-in-Csharp-Net.html

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.