173 votes

Comment vérifier si IEnumerable est null ou vide ?

J'aime string.IsNullOrEmpty méthode. J'aimerais avoir quelque chose qui permette la même fonctionnalité pour IEnumerable. Est-ce que cela existe ? Peut-être une classe d'aide pour les collections ? La raison de ma question est que dans if les déclarations, le code semble encombré si la patte est (mylist != null && mylist.Any()) . Il serait beaucoup plus propre d'avoir Foo.IsAny(myList) .

Ce post ne donne pas cette réponse : IEnumerable est vide ? .

1 votes

@msarchet : Je te donnerais probablement la réponse si ce n'était pas le commentaire :).

1 votes

Pour moi, cela ressemble à un problème XY. au lieu de demander "comment puis-je vérifier la nullité exactement partout sans que cela soit si gênant", vous devriez vous demander "comment puis-je améliorer ma conception pour ne pas avoir à vérifier la nullité partout" ?

0 votes

Vous pouvez utiliser la ligne suivante à la place : myCollection ?.FirstOrDefault() == null

214voto

Marc Gravell Points 482669

Bien sûr. pourrait écrivez ça :

public static class Utils {
    public static bool IsAny<T>(this IEnumerable<T> data) {
        return data != null && data.Any();
    }
}

Cependant, il faut être conscient que toutes les séquences ne sont pas reproductibles ; généralement Je préfère ne les promener qu'une fois, juste au cas où.

12 votes

Est-ce un bon modèle ? Je laisserais tomber le this là - je considère les méthodes d'extension qui sont supposées être appelées sur null comme le signe d'un design moche.

32 votes

@Mormegil Pourquoi ? Les méthodes d'extension donnent enfin au C# la possibilité de travailler avec des nuls, ce que d'autres langages (comme Ruby) considèrent comme acquis.

5 votes

Pourquoi est-ce que nécessairement mauvais ? Comme dans ce cas, c'est parfois très pratique car cela permet de traiter les choses de manière plus homogène et avec moins de cas particuliers.

124voto

Matt Greer Points 29401
public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable) {
    return enumerable == null || !enumerable.Any();
}

8 votes

Eh bien, pas tout à fait, le PO a demandé IEnumerable, pas IEnumerable<T> ;-)

13 votes

Oui, IEnumerable n'a pas Any() extension.

25voto

yoyo Points 802

Voici une version modifiée de la réponse utile de @Matt Greer qui inclut une classe wrapper statique afin que vous puissiez simplement la copier-coller dans un nouveau fichier source, qui ne dépend pas de Linq et qui ajoute une fonction générique de type IEnumerable<T> pour éviter la mise en boîte des types de valeurs qui se produirait avec la version non générique. [EDIT : Notez que l'utilisation de IEnumerable<T> n'empêche pas la mise en boîte de l'énumérateur, Dactylographie en canard ne peut pas empêcher cela, mais au moins les éléments d'une collection à valeur ne seront pas tous encadrés].

using System.Collections;
using System.Collections.Generic;

public static class IsNullOrEmptyExtension
{
    public static bool IsNullOrEmpty(this IEnumerable source)
    {
        if (source != null)
        {
            foreach (object obj in source)
            {
                return false;
            }
        }
        return true;
    }

    public static bool IsNullOrEmpty<T>(this IEnumerable<T> source)
    {
        if (source != null)
        {
            foreach (T obj in source)
            {
                return false;
            }
        }
        return true;
    }
}

3voto

vlad Points 3067

Je ne pense pas que cette fonction existe, mais vous pouvez toujours créer une petite fonction d'aide qui fait exactement ce que vous avez dit pour accomplir la même chose, tout en réduisant l'encombrement de votre if déclarations.

2voto

Don Kirkby Points 12671

Voici le code de La réponse de Marc Gravell ainsi qu'un exemple de son utilisation.

using System;
using System.Collections.Generic;
using System.Linq;

public static class Utils
{
    public static bool IsAny<T>(this IEnumerable<T> data)
    {
        return data != null && data.Any();
    }
}

class Program
{
    static void Main(string[] args)
    {
        IEnumerable<string> items;
        //items = null;
        //items = new String[0];
        items = new String[] { "foo", "bar", "baz" };

        /*** Example Starts Here ***/
        if (items.IsAny())
        {
            foreach (var item in items)
            {
                Console.WriteLine(item);
            }
        }
        else
        {
            Console.WriteLine("No items.");
        }
    }
}

Comme il le dit, toutes les séquences ne sont pas répétables, de sorte que ce code peut parfois poser des problèmes, car IsAny() commence à parcourir la séquence. Je soupçonne que ce qui Réponse de Robert Harvey voulait dire que vous n'avez souvent pas besoin de vérifier pour null et vide. Souvent, vous pouvez simplement vérifier s'il y a null et ensuite utiliser foreach .

Pour éviter de démarrer la séquence deux fois et profiter de l'avantage de foreach Je viens d'écrire un code comme celui-ci :

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        IEnumerable<string> items;
        //items = null;
        //items = new String[0];
        items = new String[] { "foo", "bar", "baz" };

        /*** Example Starts Here ***/
        bool isEmpty = true;
        if (items != null)
        {
            foreach (var item in items)
            {
                isEmpty = false;
                Console.WriteLine(item);
            }
        }
        if (isEmpty)
        {
            Console.WriteLine("No items.");
        }
    }
}

Je suppose que la méthode d'extension vous permet d'économiser quelques lignes de saisie, mais ce code me semble plus clair. Je soupçonne que certains développeurs ne réaliseraient pas immédiatement que IsAny(items) va commencer à parcourir la séquence. (Bien sûr, si vous utilisez beaucoup de séquences, vous apprenez rapidement à réfléchir à ce qui les traverse).

0 votes

Si vous appelez IsAny sur un null, une exception sera levée.

3 votes

L'avez-vous essayé, @Ace ? Il semblerait que cela lève une exception, mais les méthodes d'extension peuvent être appelées sur des instances nulles .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X