Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IsPrimitive doesn't include nullable primitive values

I want to check if a Type is primitive or not and used the following code:

return type.IsValueType && type.IsPrimitive;

This works fine aslong as the primitive isnt nullable. For example int?, how can I check if the type is a nullable primitive type? (FYI: type.IsPrimitive == false on int?)

like image 447
Rand Random Avatar asked Jan 07 '14 14:01

Rand Random


3 Answers

First you'll need to determine if it's Nullable<> and then you'll need to grab the nullable types:

if (type.IsGenericType
    && type.GetGenericTypeDefinition() == typeof(Nullable<>)
    && type.GetGenericArguments().Any(t => t.IsValueType && t.IsPrimitive))
{
    // it's a nullable primitive
}

Now, the aforementioned works, but not recursively. To get it to work recursively you'll need to put this into a method that you can call recursively for all types in GetGenericArguments. However, don't do that if it's not necessary.

That code may also be able to be converted to this:

if (type.GetGenericArguments().Any(t => t.IsValueType && t.IsPrimitive))
{
    // it's a nullable primitive
}

but the caveat there is that it may be a generic reference type and may not actually meet the definition of primitive for your needs. Again, remember, the aforementioned is more concise but could return a false positive.

like image 161
Mike Perrenoud Avatar answered Oct 12 '22 19:10

Mike Perrenoud


From MSDN:

The primitive types are Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, and Single.

So basically you should expect Nullable<Int32> to not be a primitive type.

You could use Nullable.GetUnderlyingType to "extract" Int32 from Nullable<Int32>.

like image 31
ken2k Avatar answered Oct 12 '22 20:10

ken2k


The reason IsPrimitive fails on Nullable<int> (also known as int?) is that Nullable<int> is not a primitive. It is an instance of a generic class Nullable<T> with the type parameter of int.

You can check if a number is a nullable primitive by verifying that

  • It is a generic type,
  • Its generic type definition is Nullable<>, and
  • Its generic parameter type IsPrimitive.
like image 35
Sergey Kalinichenko Avatar answered Oct 12 '22 20:10

Sergey Kalinichenko