У меня есть несколько методов, которые я написал в своей служебной библиотеке, на которые я сильно полагался. Первый - это метод, который преобразует любой тип в соответствующую ему форму Nullable <Type>:
public static Type GetNullableType(Type TypeToConvert)
{
if (TypeToConvert == null)
return null;
if (IsTypeNullable(TypeToConvert))
return TypeToConvert;
if (TypeToConvert.IsValueType && TypeToConvert != typeof(void))
return typeof(Nullable<>).MakeGenericType(TypeToConvert);
return null;
}
Второй метод просто сообщает, допускает ли данный Тип значение NULL. Этот метод вызывается первым и полезен отдельно:
public static bool IsTypeNullable(Type TypeToTest)
{
if (TypeToTest == null)
return false;
if (!TypeToTest.IsValueType)
return true;
return TypeToTest.IsGenericType && TypeToTest.GetGenericTypeDefinition() == typeof(Nullable<>);
}
Вышеупомянутая реализация IsTypeNullable каждый раз работает как чемпион, но в последней строке кода она немного многословна и медленна. Следующее тело кода такое же, как и выше для IsTypeNullable, за исключением того, что последняя строка кода проще и быстрее:
if (TypeToTest == null)
return false;
if (!TypeToTest.IsValueType)
return true;
return Nullable.GetUnderlyingType(TypeToTest) != null;
Наслаждайтесь!
отметка
PS - Насчет "нулевой возможности"
Я должен повторить заявление о допустимости пустых значений, которое я сделал в отдельном сообщении, которое непосредственно относится к правильному рассмотрению этой темы. То есть, я считаю, что основное внимание здесь должно уделяться не тому, как проверить, является ли объект универсальным типом Nullable, а скорее тому, можно ли присвоить значение null объекту этого типа. Другими словами, я думаю, что мы должны определять, допускает ли тип объекта значение NULL, а не его значение. Разница заключается в семантике, а именно в практических причинах определения допустимости значений NULL, что обычно и имеет значение.
В системе, использующей объекты с типами, которые, возможно, неизвестны до времени выполнения (веб-службы, удаленные вызовы, базы данных, каналы и т. Д.), Общим требованием является определение того, может ли объекту быть присвоено значение null или может ли объект содержать нуль. Выполнение таких операций с типами, не допускающими значения NULL, скорее всего, приведет к ошибкам, обычно исключениям, которые очень дороги как с точки зрения производительности, так и требований кодирования. Чтобы воспользоваться наиболее предпочтительным подходом к упреждающему предотвращению таких проблем, необходимо определить, может ли объект произвольного типа содержать значение null; то есть, является ли он вообще «допускающим значение NULL».
В очень практическом и типичном смысле допустимость значений NULL в терминах .NET вовсе не обязательно означает, что Type объекта является формой Nullable. Фактически во многих случаях объекты имеют ссылочные типы, могут содержать нулевое значение и, таким образом, все могут иметь нулевое значение; ни у одного из них нет типа, допускающего значение NULL. Поэтому для практических целей в большинстве сценариев следует проводить тестирование общей концепции допустимости значений NULL, а не концепции Nullable, зависящей от реализации. Таким образом, нам не следует зацикливаться исключительно на типе .NET Nullable, а лучше включить наше понимание его требований и поведения в процесс сосредоточения внимания на общей практической концепции допустимости значений NULL.