web-dev-qa-db-fra.com

Comment déterminer si un type est un type de collection?

J'essaie de déterminer si un type d'exécution est une sorte de type de collection. Ce que j'ai ci-dessous fonctionne, mais il semble étrange que je doive nommer les types que je crois être des types de collection dans un tableau comme je l'ai fait.

Dans le code ci-dessous, la raison de la logique générique est que, dans mon application, je m'attends à ce que toutes les collections soient génériques.

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

Comment pourrais-je refactoriser ce code pour qu'il soit plus intelligent ou plus simple?

40
Byron Sommardahl

Vraiment tous ces types héritent IEnumerable . Vous ne pouvez vérifier que pour cela:

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

ou si vous avez vraiment besoin de vérifier ICollection:

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

Regardez la partie "Syntaxe":

74
Ruben

Je sais que ce fil est ancien mais voici un exemple moderne au 20 juillet 2015 selon Microsoft is mot-clé.

if(collection is ICollection) return true;
3

Vous pouvez utiliser cette méthode d'assistance pour vérifier si un type implémente une interface générique ouverte. Dans votre cas, vous pouvez utiliser 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;
}

Ou vous pouvez simplement vérifier le IEnumerable non générique. Toutes les interfaces de collection en héritent. Mais je n'appellerais aucun type qui implémente IEnumerable une collection.

2
CodesInChaos

Tous héritent de IEnumerable (), ce qui signifie que vérifier c'est là devrait suffire:

1
YavgenyP

Vous pouvez utiliser linq, rechercher un nom d'interface comme

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

Si cela a des valeurs, c'est une instance de IEnumerable.

1
salvador