why is typeof int?
an Int32
int? x = 1;
Console.WriteLine(x.GetType().Name);
If it is okay then what\'s the use of
Mainly its for dealing with a generic method:: e.g.
public static void SomeMethod<T>(T argument)
{
if(Nullable.GetUnderlyingType(typeof(T) != null)
{
/* special case for nullable code go here */
}
else
{
/* Do something else T isn't nullable */
}
}
It's important to know this, as certain things that are very cheap can be wildly expensive on nullable's. For instance, if(argument == null)
is normally super cheap, but when done in a generic method on a Nullable<T>
is forced to box the argument
to get a null reference. Your best bet is to use EqualityComparer<T>.Default
which will slow everything else down, but makes nullable's not suffer.
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.
When you write int?
it's as if you've written Nullable<int>
. That's the type you're looking for, I think.
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.
This example is a bit confused, because:
int? x = 1;
creates a Nullable<int>
like you expect; however:
Type tupe = 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
}
}