Qu'est-ce qu'un code solide, élégant et réutilisable pour déterminer si un IEnumerable est vide, dans .NET?

StackOverflow https://stackoverflow.com/questions/117355

  •  02-07-2019
  •  | 
  •  

Question

J'essaie de trouver le code le plus réutilisable, mais le plus élégant, possible pour déterminer s'il s'agit d'un IEnumerable. Dans l’idéal, c’est une fonction que je peux appeler absolument chaque fois que j’ai besoin de savoir si un IEnumerable est vide.

Alors que j'ai développé une réponse pour .NET 3.5 qui a bien fonctionné pour moi jusqu'à présent, ma pensée actuelle est qu'il n'y a pas de réponse parfaite, puisqu'un IEnumerable peut encapsuler techniquement une collection (ou une file d'itérateurs) qui modifie la résultats sous-jacents car il itère, ce qui causerait des problèmes. Cependant, cela constituerait également un obstacle à la mise en oeuvre de IEnumerable.Count (), ce qui n’a pas empêché MS de le fournir.

Je pensais donc que je le mettrais à SO pour voir si quelqu'un en avait un meilleur, et au cas où quelqu'un le trouverait utile.

Modifier: Wow, je ne peux pas croire que je ne connaissais pas IEnumerable.Any. Je savais que cela existait, mais je n'ai jamais pris la peine de vérifier ce qu'il faisait. Que cela soit une leçon. Lisez la documentation. Ce n'est pas parce qu'un nom de méthode n'implique pas qu'il fait ce que vous voulez. Il ne fait pas ce que vous voulez.

Était-ce utile?

La solution

!enumerable.Any()

Essayera d'attraper le premier élément uniquement.

Pour expliquer comment et pourquoi cela fonctionne, any détermine si l'un des composants d'une IEnumerable correspondance à une fonction donnée, si aucun élément n'est spécifié, tout composant réussira, ce qui signifie que la fonction retournera la valeur true si un élément existe. dans l'énumérable.

Autres conseils

Pour .net 1/2:

IEnumerator e;
try
{
   e = enumerable.GetEnumerator();
   return e.MoveNext();
}
finally
{ 
    if (e is IDisposable)
        e.Dispose();
}

Ou, avec les génériques:

using (IEnumerator<T> e = enumerable.GetEnumerator())
{
    return e.MoveNext();
}

Vous avez raison, il n'y a pas de réponse parfaite. IEnumerable ne prend en charge que l'itération et ne garantit pas que l'énumération est répétable. Vous ne pouvez pas savoir si une énumération contient des éléments sans appeler MoveNext au moins une fois. Une fois que vous avez terminé, vous ne pouvez pas garantir de pouvoir réutiliser l'énumération: elle est autorisée pour IEnumerable.Reset pour générer une exception NotSupportedException. De http://msdn.microsoft.com/fr -us / library / system.collections.ienumerator.reset.aspx :

& "; La méthode de réinitialisation est fournie pour l'interopérabilité COM. Il n'est pas nécessairement nécessaire de la mettre en œuvre. au lieu de cela, l’implémenteur peut simplement lever une exception NotSupportedException. "

Des méthodes d'extension telles que IEnumerable < T > .Count et IEnumerable < T > .Tout besoin d'appeler MoveNext sous la couverture. Des wrappers utiles, mais n’évitez pas le fait que dans les (rares) cas où une énumération ne prend pas en charge la réinitialisation, vous pourriez avoir un problème.

Une chose à laquelle il faut faire attention avec l'une ou l'autre de ces méthodes est que toutes les énumérations ne peuvent pas être restaurées, par exemple toutes les implémentations de System.Data.IDataReader ne peuvent être exécutées qu'une seule fois.

Dans ces cas, vous n'avez pas vraiment de coût dans une boucle foreach, tant que vous tenez compte du fait qu'il n'est peut-être même pas en boucle une fois.

La première méthode a une implémentation simple de la méthode d’extension vide: http://signum.codeplex.com/SourceControl/changeset/view/25903# 510468

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top