Comment supprimer tous les éléments nuls dans une liste générique en une seule fois?


112

Existe-t-il une méthode par défaut définie dans .Net pour C # pour supprimer tous les éléments d'une liste qui le sont null?

List<EmailParameterClass> parameterList = new List<EmailParameterClass>{param1, param2, param3...};

Disons que certains des paramètres sont null; Je ne peux pas savoir à l'avance et je souhaite les supprimer de ma liste afin qu'elle ne contienne que des paramètres qui ne sont pas nuls.

Réponses:


225

Vous voudrez probablement ce qui suit.

List<EmailParameterClass> parameterList = new List<EmailParameterClass>{param1, param2, param3...};
parameterList.RemoveAll(item => item == null);

4
Oui, c'est la même chose que ma réponse mais en utilisant la nouvelle syntaxe lambda C # 3.
Mark Bell

@Mark: J'ai vu les secondes affichées et mec c'était proche (32, 33 et 34). ;)
Lance le

1
Ouais ... eh bien votre réponse fonctionne même dans les anciennes versions donc +1! Alors là, ha! ; Þ
Lance le

43

Je ne connais aucune méthode intégrée, mais vous pouvez simplement utiliser linq:

parameterList = parameterList.Where(x => x != null).ToList();

5
Cela doit être évité s'il parameterLists'agit déjà d'une liste, car cela créera inutilement une nouvelle copie. Dans ce cas, utilisez la RemoveAllméthode comme d'autres suggèrent.
Nick

C'est probablement la meilleure option si la collection est un fichier Array.
Andrew

25

La méthode RemoveAll devrait faire l'affaire:

parameterList.RemoveAll(delegate (object o) { return o == null; });

Pourquoi ne pas utiliser le lambda?
Mike de Klerk

12
C'est une réponse vieille de quatre ans. À l'époque, C # 3 était relativement nouveau et j'utilisais toujours C # 2 au jour le jour. La syntaxe lambda est maintenant la voie à suivre; cependant, c'est toujours une réponse de travail, donc je l'ai laissée ici pour quiconque ne peut pas utiliser la nouvelle syntaxe (pour une raison quelconque).
Mark Bell

2
Je ne savais pas que la syntaxe lambda était venue plus tard. Merci pour ton explication! Sans aucun doute, c'est valable.
Mike de Klerk

8

La méthode OfType()ignorera les valeurs nulles:

List<EmailParameterClass> parameterList =
    new List<EmailParameterClass>{param1, param2, param3...};

IList<EmailParameterClass> parameterList_notnull = 
    parameterList.OfType<EmailParameterClass>();

D'une certaine manière, c'est une bonne approche, mais cela surprend le développeur qui pense juste qu'il OfTypesélectionne des objets d'un certain type, sans penser qu'il n'inclura pas de nullvaleurs ... Donc je suis un peu fatigué d'introduire ceci dans mon propre code.

@ BjörnAliGöransson D'accord. C'est une solution intéressante, mais elle ne se «lit» pas très clairement. L'utilisation de .RemoveAll avec un lambda garde toujours tout sur une seule ligne tout en rendant vraiment évident ce que le développeur qui l'a écrit essayait de réaliser. Cependant, cela peut être utile s'il y a un avantage de vitesse qui en vaut la peine.
MattD

4
List<EmailParameterClass> parameterList = new List<EmailParameterClass>{param1, param2, param3...};

parameterList = parameterList.Where(param => param != null).ToList();

2

Facile et sans LINQ:

while (parameterList.Remove(null)) {};

Cette méthode est en Listclasse juste à côté RemoveAll, donc je recommanderais celle-là pour plus de clarté. Si les performances s'avéraient cruciales, vous pouvez adopter cette approche (même si je supprimerais les crochets et ajouterais probablement un commentaire pour les développeurs inconscients).
Andrew

1
@Andrew: selon MSDN, RemoveAll ne prend pas null. Je pense que j'ai également testé cela. Un commentaire a cependant du sens.
Tobias Knauss

1
RemoveAlla reçu un Predicate, vous devez donc utiliser RemoveAll(x => x == null), comme indiqué dans la réponse acceptée et de Mark Bell.
Andrew

1

Il existe une autre option simple et élégante:

parameters.OfType<EmailParameterClass>();

Cela supprimera tous les éléments qui ne sont pas de type, EmailParameterClassce qui filtrera évidemment tous les éléments de type null.

Voici un test:

class Test { }
class Program
{
    static void Main(string[] args)
    {
        var list = new List<Test>();
        list.Add(null);
        Console.WriteLine(list.OfType<Test>().Count());// 0
        list.Add(new Test());
        Console.WriteLine(list.OfType<Test>().Count());// 1
        Test test = null;
        list.Add(test);
        Console.WriteLine(list.OfType<Test>().Count());// 1
        Console.ReadKey();
    }
}

Est-ce que ça va marcher? les références d'élément ne seront-elles pas encore de type EmailParameterClasset n'auront-elles qu'une valeur égale à null?
derHugo

Ce sera certainement le cas et j'ai ajouté un testeur pour votre divertissement.
Ryan Naccarato le
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.