2009-03-12 4 views
9

Ich muss ein Objekt validieren, um zu sehen, ob es Null ist, ein Werttyp, oder IEnumerable<T>, wobei T ein Werttyp ist. Bisher habe ich:Wie finde ich heraus, ob der Objekttyp eine Unterklasse von IEnumerable <T> für einen beliebigen Werttyp T ist?

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. 
} 

So habe ich festgestellt, dass das Objekt null ist, ein Werttyp oder IEnumerable<T> für einige T; Wie überprüfe ich, ob T ein Werttyp ist?

Antwort

12

(edit - Mehrwert Typ Bits)

Sie müssen alle Schnittstellen überprüfen es implementiert (beachten Sie, es in der Theorie IEnumerable<T> für mehrere T implementieren könnte):

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

Ist GetInterfaces ausreichend rekursive Sie bedeuten nicht, die Eltern über das Gehen auf Grund zur Sorge Arten? –

+0

@Jon: Ich denke schon, ja. –

+1

Sie brauchen keine Rekursion. Eine Klasse implementiert entweder eine Schnittstelle oder sie tut dies nicht. Es ist eine flache Liste, unabhängig davon, wie die Schnittstellen sich gegenseitig "erben". – Tar

0

Können Sie tun somethin mit GetGenericArguments?

0

Mein generic Beitrag, der überprüft, ob eine bestimmte Art (oder dessen Basisklassen) implementiert eine Schnittstelle vom Typ 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; 
}