Как узнать, является ли тип объекта подклассом IEnumerable <T>для любого типа значения T? - PullRequest
9 голосов
/ 12 марта 2009

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

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

Ответы [ 3 ]

12 голосов
/ 12 марта 2009

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

Вам необходимо проверить все реализуемые им интерфейсы (обратите внимание, что теоретически он может реализовать 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);
    }
}
0 голосов
/ 22 мая 2014

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...