【问题标题】:How to determine if a type is a type of collection?如何判断一个类型是否是一个集合类型?
【发布时间】:2012-06-07 12:58:44
【问题描述】:

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

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

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

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

【问题讨论】:

  • 要记住的一点是,您通常不想将string 视为chars 的集合,即使它实现了IEnumerable&lt;char&gt;

标签: c# collections types refactoring


【解决方案1】:

实际上所有这些类型都继承了IEnumerable。您只能检查它:

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

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

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

查看“语法”部分:

【讨论】:

  • 哈哈。真的就这么简单。出于某种原因,我认为这行不通,我没有尝试。
  • 文档中的继承层次结构不会告诉您实现的接口。但是看看语法部分会。
  • @Ruben,这正是我的意思,但这不在继承层次结构部分。
  • 检查IEnumerable 存在将string 错误解释为集合的问题。大多数时候这是不可取的。
  • 根本不适合我。 ICollection&lt;CPerson&gt;type.GetInterface("ICollection")type.GetInterface("System.Collections.Generic.ICollection") 上返回null
【解决方案2】:

你可以使用这个辅助方法来检查一个类型是否实现了一个开放的泛型接口。在您的情况下,您可以使用DoesTypeSupportInterface(type, typeof(Collection&lt;&gt;))

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 的类型称为集合。

【讨论】:

  • 或者使用解决方案found here,除了泛型接口之外,它还适用于泛型类型。
【解决方案3】:

你可以使用linq,搜索一个接口名比如

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

如果这有值是IEnumerable 的一个实例。

【讨论】:

  • 导致误报的字符串也是如此
  • String 是一个字符集合,所以它不是误报。也许这不是你要找的
【解决方案4】:

此解决方案将处理ICollectionICollection&lt;T&gt;

    static bool IsCollectionType(Type type)
    {
        return type.GetInterfaces().Any(s => s.Namespace == "System.Collections.Generic" && (s.Name == "ICollection" || s.Name.StartsWith("ICollection`")));
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-14
    • 2014-09-17
    • 2010-09-17
    相关资源
    最近更新 更多