why is typeof int?
an Int32
int? x = 1;
Console.WriteLine(x.GetType().Name);
If it is okay then what's the use of Nullable.GetUnderlyingType
?
You typically use a nullable value type when you need to represent the undefined value of an underlying value type. For example, a Boolean, or bool , variable can only be either true or false .
The Nullable type allows you to assign a null value to a variable. Nullable types introduced in C#2.0 can only work with Value Type, not with Reference Type. The nullable types for Reference Type is introduced later in C# 8.0 in 2019 so that we can explicitly define if a reference type can or can not hold a null value.
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.
No difference. int? is just shorthand for Nullable<int> , which itself is shorthand for Nullable<Int32> . Compiled code will be exactly the same whichever one you choose to use.
Calling GetType()
boxes your variable. The CLR has a special rule that Nullable<T>
gets boxed to T
. So x.GetType
will return Int32
instead of Nullable<Int32>
.
int? x = 1;
x.GetType() //Int32
typeof(int?) //Nullable<Int32>
Since a Nullable
containing null
will be boxed to null
the following will throw an exception:
int? x = null;
x.GetType() //throws NullReferenceException
To quote MSDN on Boxing Nullable Types:
Objects based on nullable types are only boxed if the object is non-null. If
HasValue
isfalse
, the object reference is assigned tonull
instead of boxingIf the object is non-null -- if
HasValue
istrue
-- then boxing occurs, but only the underlying type that the nullable object is based on is boxed. Boxing a non-null nullable value type boxes the value type itself, not theSystem.Nullable<T>
that wraps the value type.
This example is a bit confused, because:
int? x = 1;
creates a Nullable<int>
like you expect; however:
Type type = x.GetType();
is a call to a non-virtual method on object
, which isn't (and can't be) overridden - therefore this is a boxing operation; and Nullable<T>
has special boxing rules:
null
i.e.
int? x = 1;
int y = 1;
box to exactly the same thing.
Therefore, you are passing typeof(int)
to GetUnderlyingType
.
A more illustrative example of when this helps is when using reflection:
class Foo {
public int? Bar {get;set;}
}
...
Type type = typeof(Foo); // usually indirectly
foreach(var prop in type.GetProperties()) {
Type propType = prop.PropertyType,
nullType = Nullable.GetUnderlyingType(propType);
if(nullType != null) {
// special code for handling Nullable<T> properties;
// note nullType now holds the T
} else {
// code for handling other properties
}
}
Its for when you don't know its Int32
.
public Type GetNullableUnderlyingType<T>(Nullable<T> obj)
where T : struct
{
return Nullable.GetUnderlyingType(typeof(Nullable<T>));
}
Here, you can pass any Nullable
object and get it to return it's underlying type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With