7
votes

Meilleure façon de tester si un type est une collection

J'ai une méthode qui accepte un paramètre obj de type system.Object

maintenant je veux vérifier si le type d'obj est:

  • Un type de collection (iEnumerable).
  • autre chose.

    Le premier moyen que j'ai pensé est: xxx

    mais système.string implémente iEnumerable, et Je ne veux pas traiter la chaîne comme Une collection .

    La deuxième façon dont j'ai pensé tester l'ICollection au lieu de iEnumerable, car iEnumerable est plus d'une collection potentielle que celle d'un. Cela laisserait une chaîne, mais aussi l'ICollection - de-t, car il n'hérite pas ICOLLECLE (iEnumerable-T est la seule abstraction de collecte générique qui est compatible à l'envers - il hérite iEnumerable).

    Donc, je suppose Le meilleur moyen est de: xxx

    y a-t-il une meilleure façon?


2 commentaires

J'utilise des énumérables comme des séquences, pas comme des collections. Il y a peut-être une différence subtile dans la signification; Puisque je ne connais pas votre candidature, je ne sais pas si cela est relavent. Nous avons fait face à ce problème lors de la conception d'initialisateurs de collecte. Il existe de nombreuses "collections" qui ne mettent pas en œuvre l'ICOLLECTION, et de nombreux objets qui implémentent ajout qui ne sont pas des collections. (Objets mathématiques, typiquement.) Nous avons décidé d'utiliser une heuristique. Si un type à la fois implémente iEnumerable et a une méthode d'ajout public, c'est probablement une collection. C'est un peu goofy, mais en pratique ça marche.


Ceci est une bonne ressource liée à propos des abstractions de collecte: blogs.msdn. com / brada / archive / 2005/01/18 / 355755.aspx


3 Réponses :


5
votes

Si vous voulez vraiment seulement tester:

bool isCollection = obj.GetType().GetInterfaces()
    .Any(iface => iface.GetGenericTypeDefinition() == typeof(ICollection<>))


1 commentaires

Ou obj.gettype (). Getterface ("System.Collections.iénumérables")! = NULL



10
votes

Je pense que vous avez un peu trop compliqué cela. Si vous voulez vraiment utiliser iEnumerable mais exclure System.string, pourquoi ne pas simplement faire cela directement dans le code? xxx


1 commentaires

Cela semble être le seul moyen de le faire. Je pense que lorsque les gars de la BCL ont conçu le type de chaîne, ils n'ont pas compris à quel point iT-IMPORTAIRE iTNUMERABLE deviendrait le seul moyen de faire référence à une collection.



-1
votes

Si vous voulez faire un chèque et que vous obtiendrez true pour TPYES (inclut des nullables) Toute liste / collection / iEnumerable, mais obtenir false pour le type de chaîne, puis

   private static bool IsIEnumerable(Type requestType)
   {
      var isIEnumerable = typeof(IEnumerable).IsAssignableFrom(requestType);
      var notString = !typeof(string).IsAssignableFrom(requestType);
      return isIEnumerable && notString;
   }


0 commentaires