49

我正在尝试确定运行时类型是否是某种集合类型。我在下面的工作,但我必须像我所做的那样在数组中命名我认为是集合类型的类型似乎很奇怪。

在下面的代码中,通用逻辑的原因是,在我的应用程序中,我希望所有集合都是通用的。

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));
}

我将如何重构此代码以使其更智能或更简单?

4

4 回答 4

88

真的所有这些类型都继承了IEnumerable. 您只能检查它:

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

或者如果你真的需要检查 ICollection:

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

查看“语法”部分:

于 2012-06-02T17:53:14.093 回答
4

你可以使用这个帮助方法来检查一个类型是否实现了一个开放的泛型接口。在您的情况下,您可以使用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集合的类型。

于 2012-06-02T17:54:51.140 回答
1

您可以使用 linq,搜索接口名称,例如

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

如果 this 有值是IEnumerable.

于 2015-09-25T19:18:19.587 回答
0

该解决方案将处理ICollectionICollection<T>

    static bool IsCollectionType(Type type)
    {
        return type.GetInterfaces().Any(s => s.Namespace == "System.Collections.Generic" && (s.Name == "ICollection" || s.Name.StartsWith("ICollection`")));
    }
于 2021-05-18T08:27:35.493 回答