If I have a Type
, is there some easy way to tell that it represents a nullable value type using Reflection? Ideally something a little cleaner (and more correct) than:
static bool IsNullable(Type type)
{
return type.IsValueType && type.Name.StartsWith("Nullable");
}
type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)
You might also find Nullable.GetUnderlyingType(Type nullableType)
useful, to easily get the T
of the typeof(Nullable<T>)
you pass in.
Although @theCoop's answer is correct (there is nothing fundamentally wrong in placing his code into the body of the method you've provided), there are some giant gotchas here.
Nullable<T>
is treated by the run-time as a 'special' type that has some very peculiar semantics. In particular, when a Nullable<T>
is boxed:
HasValue == true
, it behaves just like a boxed T
, making it impossible for downsteam code to tell if the created object was produced by boxing a T
or by boxing a Nullable<T>
.
Unboxing to T
and Nullable<T>
are both possible.HasValue == false
, boxing simply returns null
. Unboxing to T
will throw, unboxing to Nullable<T>
will succeed, for which HasValue == false
. In either case, boxedNullableObject.GetType()
will not reveal that the object was produced by boxing a Nullable<T>.
I can't think of any other value-type that exhibits such strange behaviour.
For example, consider:
// Output: "System.Nullable`1[System.Int32]"
Console.WriteLine(typeof(int?));
object boxedNullableInt32WithValue = new int?(0);
// Output: "System.Int32", NOT "System.Nullable`1[System.Int32]"
Console.WriteLine(boxedNullableInt32WithValue.GetType());
object boxedNullableInt32WithoutValue = new int?();
// NullReferenceException is thrown
Console.WriteLine(boxedNullableInt32WithoutValue.GetType());
Consequently, writing a method such as:
public static bool IsObjectANullableT(this object obj) { ... }
is a really bad idea.
EDIT: On another note, I just realized there is a framework method that does what you need using the same technique as @theCoop's sample:Nullable.GetUnderlyingType
.
Usage:
static bool IsNullable(Type type)
{
return Nullable.GetUnderlyingType(type) != null;
}
EDIT: Just saw that this too was mentioned by @TheCoop in his answer. My mistake.
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