Подтвердить что ты не робот

Как определить, является ли тип типом коллекции?

Я пытаюсь определить, является ли тип среды выполнения своего рода типом коллекции. То, что у меня ниже, работает, но мне кажется странным, что я должен назвать типы, которые, по моему мнению, являются типами коллекций в массиве, как я это делал.

В приведенном ниже коде причина общей логики заключается в том, что в моем приложении я ожидаю, что все коллекции будут универсальными.

bool IsCollectionType(Type type)
{
    if (!type.GetGenericArguments().Any())
        return false;

    Type genericTypeDefinition = type.GetGenericTypeDefinition();
    var collectionTypes = new[] { typeof(IEnumerable<>), typeof(ICollection<>), typeof(IList<>), typeof(List<>) };
    return collectionTypes.Any(x => x.IsAssignableFrom(genericTypeDefinition));
}

Как бы я мог реорганизовать этот код умнее или проще?

4b9b3361

Ответ 1

Действительно, все эти типы наследуют IEnumerable. Вы можете проверить только его:

bool IsEnumerableType(Type type)
{
    return (type.GetInterface(nameof(IEnumerable)) != null);
}

или если вам действительно нужно проверить ICollection:

bool IsCollectionType(Type type)
{
    return (type.GetInterface(nameof(ICollection)) != null);
}

Посмотрите на часть "Синтаксис":

Ответ 2

Вы можете использовать этот вспомогательный метод, чтобы проверить, реализует ли тип открытого общего интерфейса. В вашем случае вы можете использовать DoesTypeSupportInterface(type, typeof(Collection<>))

public static bool DoesTypeSupportInterface(Type type,Type inter)
{
    if(inter.IsAssignableFrom(type))
        return true;
    if(type.GetInterfaces().Any(i=>i. IsGenericType && i.GetGenericTypeDefinition()==inter))
        return true;
    return false;
}

Или вы можете просто проверить не общий IEnumerable. Все интерфейсы коллекции наследуются от него. Но я бы не назвал тип, реализующий IEnumerable коллекцию.

Ответ 3

Я знаю, что эта ветка устарела, но вот современный пример с 20 июля 2015 года в соответствии с Microsoft является ключевым словом.

if(collection is ICollection) return true;

Ответ 4

Все они наследуют IEnumerable(), что означает, что проверка его там должна быть достаточной:

Ответ 5

Вы можете использовать linq, искать имя интерфейса, например

yourobject.GetType().GetInterfaces().Where(s => s.Name == "IEnumerable")

Если это значение является экземпляром IEnumerable.