Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why GetType returns System.Int32 instead of Nullable<Int32>? [duplicate]

Why is the output of this snippet System.Int32 instead of Nullable<Int32>?

int? x = 5; Console.WriteLine(x.GetType()); 
like image 910
Arsen Mkrtchyan Avatar asked Aug 03 '11 19:08

Arsen Mkrtchyan


People also ask

Can Int32 be null?

Here, T represents the data type of the variable. The following statement would not compile as you cannot assign a null value to a value type. Int32 i = null; To assign a null value to a value type, you need to take advantage of a nullable type as shown in the code snippet below.

What is the default value of Nullable int C#?

The default value of a bool variable in C# is false (reference). Therefore, the HasValue property of a default Nullable<T> instance is false ; which in turn makes that Nullable<T> instance itself act like null .

How do you make an INT Nullable in C#?

As you know, a value type cannot be assigned a null value. For example, int i = null will give you a compile time error. C# 2.0 introduced nullable types that allow you to assign null to value type variables. You can declare nullable types using Nullable<t> where T is a type.


2 Answers

GetType() is a method of object.
To call it, the Nullable<T> struct must be boxed.

You can see this in the IL code:

//int? x = 5; IL_0000:  ldloca.s    00  IL_0002:  ldc.i4.5     IL_0003:  call        System.Nullable<System.Int32>..ctor  //Console.WriteLine(x.GetType()); IL_0008:  ldloc.0      IL_0009:  box         System.Nullable<System.Int32> IL_000E:  callvirt    System.Object.GetType IL_0013:  call        System.Console.WriteLine 

Nullable types are treated specially by CLR; it is impossible to have a boxed instance of a nullable type.
Instead, boxing a nullable type will result in a null reference (if HasValue is false), or the boxed value (if there is a value).

Therefore, the box System.Nullable<System.Int32> instruction results in a boxed Int32, not a boxed Nullable<Int32>.

Therefore, it is impossible for GetType() to ever return Nullable<T>.

To see this more clearly, look at the following code:

static void Main() {     int? x = 5;     PrintType(x);    } static void PrintType<T>(T val) {     Console.WriteLine("Compile-time type: " + typeof(T));     Console.WriteLine("Run-time type: " + val.GetType()); } 

This prints

Compile-time type: System.Nullable`1[System.Int32]
Run-time type: System.Int32

like image 108
SLaks Avatar answered Sep 21 '22 19:09

SLaks


GetType() isn't virtual, and is thus defined only on object. As such, to make the call, the Nullable<Int32> must first be boxed. Nullables have special boxing rules, though, so only the Int32 value is boxed, and that's the type reported.

like image 41
dlev Avatar answered Sep 24 '22 19:09

dlev