2009-03-12 9 views
9

Potrzebuję sprawdzić poprawność obiektu, aby zobaczyć, czy jest on pusty, typ wartości lub IEnumerable<T>, gdzie T jest typem wartości. Do tej pory mam:Jak dowiedzieć się, czy typ obiektu jest podklasą IEnumerable <T> dla dowolnego typu wartości T?

if ((obj == null) || 
    (obj .GetType().IsValueType)) 
{ 
    valid = true; 
} 
else if (obj.GetType().IsSubclassOf(typeof(IEnumerable<>))) 
{ 
    // TODO: check whether the generic parameter is a value type. 
} 

więc znalazłem, że obiekt jest null, typ wartości, lub IEnumerable<T> dla niektórych T; jak sprawdzić, czy ten T jest typem wartości?

Odpowiedz

12

(Edit - dodaje bity typu value)

Trzeba sprawdzić wszystkie interfejsy implementuje (nota teoretycznie może on realizować IEnumerable<T> dla wielu T):

foreach (Type interfaceType in obj.GetType().GetInterfaces()) 
{ 
    if (interfaceType.IsGenericType 
     && interfaceType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) 
    { 
     Type itemType = interfaceType.GetGenericArguments()[0]; 
     if(!itemType.IsValueType) continue; 
     Console.WriteLine("IEnumerable-of-" + itemType.FullName); 
    } 
} 
+1

Czy GetInterfaces wystarczająco rekurencyjne oznaczać nie trzeba się martwić o dzieje się rodzica typy? –

+0

@Jon: Tak myślę, tak. –

+1

Nie potrzebujesz rekursji. Klasa albo implementuje interfejs, albo nie. Jest to płaska lista, niezależnie od tego, jak interfejsy się "dziedziczą" nawzajem. – Tar

0

Czy można zrobić coś z GetGenericArguments?

0

Moja generic wkład, który sprawdza, czy dany typ (lub jego klasy bazowe) implementuje interfejs typu T:

public static bool ImplementsInterface(this Type type, Type interfaceType) 
{ 
    while (type != null && type != typeof(object)) 
    { 
     if (type.GetInterfaces().Any(@interface => 
      @interface.IsGenericType 
      && @interface.GetGenericTypeDefinition() == interfaceType)) 
     { 
      return true; 
     } 

     type = type.BaseType; 
    } 

    return false; 
} 
Powiązane problemy