why is typeof int? an Int32
int? x = 1;
Console.WriteLine(x.GetType().Name);
If it is okay then what's the use 开发者_StackOverflow中文版of Nullable.GetUnderlyingType?
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
HasValueisfalse, the object reference is assigned tonullinstead of boxingIf the object is non-null -- if
HasValueistrue-- 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:
- if it is empty, it boxes to
null - if it has a value, the value is boxed and returned
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.
Example:
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.
When you write int? it's as if you've written Nullable<int>. That's the type you're looking for, I think.
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.
加载中,请稍侯......
精彩评论