У моїй бібліотеці є кілька методів, на які я дуже покладався. Перший - це метод, який перетворює будь-який тип у відповідну форму 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;
}
Другий метод просто повідомляє про те, чи даний Тип є нульовим. Цей метод називається першим і корисний окремо:
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, а не NULLABLE. Різниця полягає в семантиці, а саме в практичних причинах визначення визнання недійсним, що, як правило, має значення.
У системі, що використовує об’єкти з типами, які, можливо, невідомі до часу виконання (веб-служби, віддалені дзвінки, бази даних, стрічки тощо), загальною вимогою є визначення, чи може об’єкту бути присвоєне значення null, чи об’єкт може містити нуль. Виконання таких операцій з ненульованими типами, ймовірно, призведе до помилок, як правило, винятків, які є дуже дорогими як з точки зору продуктивності, так і вимог до кодування. Щоб скористатися вкрай бажаним підходом щодо попереджувального уникнення таких проблем, необхідно визначити, чи здатний об’єкт довільного типу містити нуль; тобто, чи є воно загалом "дозвільним".
У дуже практичному і типовому сенсі, можливість дозволеності в термінах .NET зовсім не означає, що Тип об'єкта є формою Nullable. Насправді в багатьох випадках об’єкти мають посилальні типи, можуть містити нульове значення і, отже, усі мають нульовий статус; жоден з них не має типу Nullable. Тому для практичних цілей у більшості сценаріїв слід проводити тестування на загальну концепцію дозволеності, ніж концепція Nullable, яка залежить від реалізації. Тому нам не слід зависати, зосередившись виключно на типі .NET Nullable, а навпаки, враховуючи наше розуміння його вимог та поведінки, у процесі зосередження уваги на загальній, практичній концепції дозволеності.