Sprawdzanie, czy wystąpienie typu jest wyliczeniem dopuszczającym wartość null w C #

85

Jak sprawdzić, czy Type jest wyliczeniem dopuszczającym wartość null w C # czymś takim jak

Type t = GetMyType();
bool isEnum = t.IsEnum; //Type member
bool isNullableEnum = t.IsNullableEnum(); How to implement this extension method?
adrin
źródło

Odpowiedzi:

171
public static bool IsNullableEnum(this Type t)
{
    Type u = Nullable.GetUnderlyingType(t);
    return (u != null) && u.IsEnum;
}
LukeH
źródło
44

EDYCJA: Zostawię tę odpowiedź, ponieważ zadziała i pokazuje kilka wezwań, o których czytelnicy mogliby nie wiedzieć. Jednak odpowiedź Łukasza jest zdecydowanie ładniejsza - zagłosuj za nią :)

Możesz to zrobić:

public static bool IsNullableEnum(this Type t)
{
    return t.IsGenericType &&
           t.GetGenericTypeDefinition() == typeof(Nullable<>) &&
           t.GetGenericArguments()[0].IsEnum;
}
Jon Skeet
źródło
Myślę, że zrobiłbym to w sposób Luke'a; mniej skomplikowane dla dzwoniącego.
Marc Gravell
2
@Marc: Nie widzę, jakie to ma szanse dla dzwoniącego - ale droga Luke'a jest z pewnością ładniejsza niż moja.
Jon Skeet
Tak, zdecydowanie zachowaj to na przyszłość
adrin
Tak. Zrobiłbym „public static bool IsNullableEnum (object value) {if (value == null) {return true;} Type t = value.GetType (); return / * to samo co Jon's return * /;}”, ponieważ może pracować z typami pudełkowymi. A potem przeciążony odpowiedzią LukeH dla lepszej wydajności.
TamusJRoyce
16

Począwszy od C # 6,0 zaakceptowaną odpowiedź można refaktoryzować jako

Nullable.GetUnderlyingType(t)?.IsEnum == true

== true jest potrzebne do konwersji bool? to bool

Bigjim
źródło
1
public static bool IsNullable(this Type type)
{
    return type.IsClass
        || (type.IsGeneric && type.GetGenericTypeDefinition == typeof(Nullable<>));
}

Pominąłem IsEnumsprawdzenie, które już zrobiłeś, ponieważ dzięki temu ta metoda jest bardziej ogólna.

Bryan Watts
źródło