Как определить, является ли тип типом коллекции?
Я пытаюсь определить, является ли тип среды выполнения своего рода типом коллекции. То, что у меня ниже, работает, но мне кажется странным, что я должен назвать типы, которые, по моему мнению, являются типами коллекций в массиве, как я это делал.
В приведенном ниже коде причина общей логики заключается в том, что в моем приложении я ожидаю, что все коллекции будут универсальными.
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));
}
Как бы я мог реорганизовать этот код умнее или проще?
Ответы
Ответ 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
.