IsPrimitive не содержит нулевых примитивных значений

Я хочу проверить, является ли тип примитивным или нет, и использовал следующий код:

return type.IsValueType && type.IsPrimitive;

Это работает отлично, поскольку примитив не имеет значения NULL. Например, int?, как я могу проверить, является ли тип примитивным типом с нулевым значением? (FYI: type.IsPrimitive == false на int?)

Ответ 1

Из MSDN:

Примитивные типы являются булевыми, байтовыми, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double и Single.

В принципе, вы должны ожидать, что Nullable<Int32> не будет примитивным типом.

Вы можете использовать Nullable.GetUnderlyingType для "извлечения" Int32 из Nullable<Int32>.

Ответ 2

Сначала вам нужно определить, если он Nullable<>, а затем вам нужно захватить типы с нулевым значением:

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

Теперь вышесказанное работает, но не рекурсивно. Чтобы заставить его работать рекурсивно, вам нужно поместить его в метод, который можно вызывать рекурсивно для всех типов в GetGenericArguments. Однако не делайте этого, если это не нужно.

Этот код также может быть преобразован в это:

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

но оговорка заключается в том, что он может быть общим эталонным типом и может не соответствовать определению примитива для ваших нужд. Опять же, помните, что вышеупомянутое является более кратким, но может вернуть ложный результат.

Ответ 3

Причина IsPrimitive не работает на Nullable<int> (также известная как int?) заключается в том, что Nullable<int> не является примитивным. Это экземпляр родового класса Nullable<T> с параметром типа int.

Вы можете проверить, является ли число нулевым примитивом, проверив, что

  • Это общий тип,
  • Его определение общего типа Nullable<> и
  • Его общий тип параметра IsPrimitive.