我试图确定运行时类型是否是某种集合类型。我在下面的工作,但似乎很奇怪,我必须像我一样在数组中命名我认为是集合类型的类型。
在下面的代码中,通用逻辑的原因是因为,在我的应用程序中,我希望所有集合都是通用的。
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));
}
我如何重构此代码以使其更智能或更简单?
答案 0 :(得分:62)
实际上所有这些类型都继承IEnumerable
。您只能检查它:
bool IsEnumerableType(Type type)
{
return (type.GetInterface(nameof(IEnumerable)) != null);
}
或者如果你真的需要检查ICollection:
bool IsCollectionType(Type type)
{
return (type.GetInterface(nameof(ICollection)) != null);
}
查看“语法”部分:
答案 1 :(得分:3)
我知道这个帖子已经过时了但是根据Microsoft is关键字,这是2015年7月20日的一个现代示例。
if(collection is ICollection) return true;
答案 2 :(得分: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 :(得分:1)
所有这些都继承了IEnumerable(),这意味着检查its there就足够了:
答案 4 :(得分:1)
您可以使用linq,搜索
等接口名称yourobject.GetType().GetInterfaces().Where(s => s.Name == "IEnumerable")
如果这个值是IEnumerable
的实例。
答案 5 :(得分:0)
此解决方案将处理 ICollection
和 ICollection<T>
。
static bool IsCollectionType(Type type)
{
return type.GetInterfaces().Any(s => s.Namespace == "System.Collections.Generic" && (s.Name == "ICollection" || s.Name.StartsWith("ICollection`")));
}