Reputation: 42246
Is there anyway to know this?
I found one post that asked a very similar question at How to check if an object is nullable? The answer explains how to determine if an object is nullable if there is access to a Generic Type Parameter. This is accomplished by using Nullabe.GetUnderlyingType(typeof(T))
. However, if you only have an object and it is not null, can you determine if it is actually a Nullable ValueType?
In other words, is there a better way than checking every possible nullable value type individually to determine if a boxed struct is a value type?
void Main(){
Console.WriteLine(Code.IsNullableStruct(Code.BoxedNullable));
}
public static class Code{
private static readonly int? _nullableInteger = 43;
public static bool IsNullableStruct(object obj){
if(obj == null) throw new ArgumentNullException("obj");
if(!obj.GetType().IsValueType) return false;
return IsNullablePrimitive(obj);
}
public static bool IsNullablePrimitive(object obj){
return obj is byte? || obj is sbyte? || obj is short? || obj is ushort? || obj is int? || obj is uint? || obj is long? || obj is ulong? || obj is float? || obj is double? || obj is char? || obj is decimal? || obj is bool? || obj is DateTime? || obj is TimeSpan?;
}
public static object BoxedNullable{
get{ return _nullableInteger; }
}
}
-
I found this article at MSDN, and it says you can't determine if a type is a Nullable struct via a call to GetType()
.
-
Apparently the method I suggested doesn't work either because int x = 4; Console.WriteLine(x is int?);
is True. (See the comment)
Upvotes: 5
Views: 587
Reputation: 1876
Nullable<> is a special class. When you try to inspect or copy a Nullable<> it is converted/boxed to either 'null' or the value type it contains. Calling GetType() would actually throw an exception if your Nullable<> doesn't have a value, or at best return the underlying type. The spoofing occurs at the lowest level. You cannot identify a Nullable<> through any kosher means.
Upvotes: 0
Reputation: 30001
When you box a nullable, it actually boxes its underlying type. Nullable<int> will turn into a boxed int. There is no way to tell if the source of an boxed value type was a Nullable.
Note that your IsNullablePrimitive
will actually return true if you pass it a non-Nullable int!
Upvotes: 1
Reputation: 34250
Quoting Jon Skeet's comment in the question you linked:
there's no such thing as a boxed nullable type - Nullable gets boxed to a null reference or a boxed int
so in your example program by the time BoxedNullable
is passed to IsNullableStruct
which takes an object
as a parameter, the value is already a boxed 43
, no longer a nullable anything. Ironically x is int?
is true
for any int
, nullable or otherwise, so that only adds to the confusion.
In any case, your original question, according to Jon's comment, doesn't seem to make sense.
Upvotes: 4
Reputation: 41246
Yes, you simply check the generic definition:
protected bool IsNullableType(Type type)
{
if(!type.IsGeneric)
return false;
return type.GetGenericDefinition() == typeof(Nullable<>);
}
Effectively, these statements are the same:
var type = typeof(Nullable<>);
var type2 = new Nullable<int>().GetType().GetGenericDefinition();
Upvotes: -1