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
.