C# 如何确定一个类型是否是一个集合类型?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10864611/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 15:34:42  来源:igfitidea点击:

How to determine if a type is a type of collection?

c#collectionstypesrefactoring

提问by Byron Sommardahl

I am trying to determine if a runtime type is some sort of collection type. What I have below works, but it seems strange that I have to name the types that I believe to be collection types in an array like I have done.

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

In the code below, the reason for the generic logic is because, in my app, I expect all collections to be generic.

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

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

How would I refactor this code to be smarter or simpler?

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

采纳答案by Ruben

Really all of these types inherit IEnumerable. You can check only for it:

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

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

or if you really need to check for ICollection:

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

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

Look at "Syntax" part:

查看“语法”部分:

回答by CodesInChaos

You can use this helper method to check if a type implements an open generic interface. In your case you can use DoesTypeSupportInterface(type, typeof(Collection<>))

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

Or you can simply check for the non generic IEnumerable. All collection interfaces inherit from it. But I wouldn't call any type that implements IEnumerablea collection.

或者您可以简单地检查非通用IEnumerable. 所有集合接口都继承自它。但我不会调用任何实现IEnumerable集合的类型。

回答by salvador

You can use linq, search for an interface name like

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

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

If this has values is a instance of IEnumerable.

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

回答by Jeffrey Ferreiras

I know this thread is old but here is a modern example as of July 20, 2015 according to Microsoft iskeyword.

我知道这个线程很旧,但根据 Microsoft is关键字,这是截至 2015 年 7 月 20 日的现代示例。

if(collection is ICollection) return true;