2009-03-12 4 views
9

Devo convalidare un oggetto per vedere se è nullo, un tipo di valore, oppure IEnumerable<T> dove T è un tipo di valore. Finora ho:Come scoprire se il tipo di un oggetto è una sottoclasse di IEnumerable <T> per qualsiasi tipo di valore 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. 
} 

Così ho scoperto che l'oggetto è nullo, un tipo di valore, o per qualche IEnumerable<T>T; come faccio a verificare se quello T è un tipo di valore?

risposta

12

(modifica - ha aggiunto tipo valore bit)

È necessario controllare tutte le interfacce che realizza (si noti che potrebbe in teoria implementare IEnumerable<T> per i molteplici 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

È getInterfaces sufficientemente ricorsiva a significare che non è necessario preoccuparsi di salire al genitore tipi? –

+0

@ Jon: Penso di sì, sì. –

+1

Non hai bisogno di ricorsione. Una classe implementa un'interfaccia o no. È un elenco semplice, indipendentemente da come le interfacce stesse "si ereditano" a vicenda. – Tar

0

Puoi fare qualcosa con GetGenericArguments?

0

mio contributo generico che controlla se un determinato tipo (o le sue classi base) implementa un'interfaccia di tipo 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; 
} 
Problemi correlati