2009-03-12 2 views
9

Мне нужно проверить объект, чтобы увидеть, является ли он нулевым, тип значения или IEnumerable<T>, где T - тип значения. До сих пор у меня есть:Как узнать, является ли тип объекта подклассом IEnumerable <T> для любого значения типа 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. 
} 

Так я обнаружил, что объект имеет нулевое значение, тип значения или IEnumerable<T> для некоторых T; как я могу проверить, является ли этот тип T?

ответ

12

(редактировать - добавил биты типа значения)

Вы должны проверить все интерфейсы, которые он реализует (обратите внимание, что теоретически может реализовать IEnumerable<T> для нескольких 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 достаточно рекурсивный означает, что вам не нужно беспокоиться о поездке до родителей типы? –

+0

@ Jon: Думаю, да, да. –

+1

Вам не нужна рекурсия. Класс либо реализует интерфейс, либо нет. Это плоский список, независимо от того, как сами интерфейсы «наследуют» друг друга. – Tar

0

Можете ли вы сделать что-нибудь с GetGenericArguments?

0

Мой общий вклад, который проверяет, является ли данный тип (или его базовые классы) реализует интерфейс типа 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; 
} 
Смежные вопросы