Mam kilka metod, które napisałem w mojej bibliotece narzędziowej, na których bardzo polegałem. Pierwsza to metoda, która konwertuje dowolny Type na odpowiadający mu formularz 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;
}
Druga metoda po prostu raportuje, czy dany typ dopuszcza wartość null. Ta metoda jest wywoływana przez pierwszą i jest przydatna osobno:
public static bool IsTypeNullable(Type TypeToTest)
{
if (TypeToTest == null)
return false;
if (!TypeToTest.IsValueType)
return true;
return TypeToTest.IsGenericType && TypeToTest.GetGenericTypeDefinition() == typeof(Nullable<>);
}
Powyższa implementacja IsTypeNullable działa jak mistrz za każdym razem, ale jest nieco rozwlekła i powolna w ostatniej linii kodu. Następująca treść kodu jest taka sama jak powyżej dla IsTypeNullable, z tą różnicą, że ostatnia linia kodu jest prostsza i szybsza:
if (TypeToTest == null)
return false;
if (!TypeToTest.IsValueType)
return true;
return Nullable.GetUnderlyingType(TypeToTest) != null;
Cieszyć się!
znak
PS - Informacje o „nullability”
Powinienem powtórzyć stwierdzenie o nieważności, które zawarłem w osobnym poście, które dotyczy bezpośrednio właściwego zajęcia się tym tematem. Oznacza to, że uważam, że dyskusja tutaj nie powinna skupiać się na tym, jak sprawdzić, czy obiekt jest ogólnym typem Nullable, ale raczej na tym, czy można przypisać wartość null obiektowi tego typu. Innymi słowy, myślę, że powinniśmy określić, czy typ obiektu dopuszcza wartość null, a nie, czy jest dopuszczalny. Różnica dotyczy semantyki, a mianowicie praktycznych powodów określania wartości zerowej, która zwykle jest wszystkim, co się liczy.
W systemie używającym obiektów o typach prawdopodobnie nieznanych do czasu wykonania (usługi sieciowe, zdalne wywołania, bazy danych, źródła danych itp.), Częstym wymaganiem jest określenie, czy obiektowi można przypisać wartość null, czy też obiekt może zawierać null. Wykonywanie takich operacji na typach niepodlegających wartości null prawdopodobnie spowoduje błędy, zwykle wyjątki, które są bardzo kosztowne zarówno pod względem wydajności, jak i wymagań dotyczących kodowania. Aby przyjąć wysoce preferowane podejście do proaktywnego unikania takich problemów, konieczne jest ustalenie, czy obiekt dowolnego typu może zawierać wartość null; tj. czy generalnie dopuszcza się zerową wartość.
W bardzo praktycznym i typowym sensie dopuszczalność wartości null w terminach .NET wcale nie musi oznaczać, że typ obiektu jest formą wartości Nullable. W rzeczywistości w wielu przypadkach obiekty mają typy referencyjne, mogą zawierać wartość null, a zatem wszystkie dopuszczają wartość null; żaden z nich nie ma typu Nullable. Dlatego ze względów praktycznych w większości scenariuszy testowanie powinno być przeprowadzane dla ogólnej koncepcji dopuszczalności wartości zerowej w porównaniu z koncepcją dopuszczalności zerowej zależnej od implementacji. Dlatego nie powinniśmy skupiać się wyłącznie na typie .NET Nullable, ale raczej uwzględnić nasze zrozumienie jego wymagań i zachowania w procesie skupiania się na ogólnej, praktycznej koncepcji zerowalności.