Come rimuovere tutti gli elementi nulli all'interno di un elenco generico in una volta sola?


112

Esiste un metodo predefinito definito in .Net per C # per rimuovere tutti gli elementi all'interno di un elenco che sono null?

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

Diciamo che alcuni dei parametri sono null; Non posso saperlo in anticipo e voglio rimuoverli dalla mia lista in modo che contenga solo parametri che non sono nulli.

Risposte:


225

Probabilmente vorrai quanto segue.

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

4
Sì, questa è la stessa della mia risposta ma utilizza la più recente sintassi lambda C # 3.
Mark Bell

@Mark: ho visto i secondi pubblicati e amico era vicino (32, 33 e 34). ;)
Lance

1
Sì ... beh, la tua risposta funziona anche nelle versioni precedenti, quindi +1! Quindi ecco, ah! ; Þ
Lance

43

Non conosco alcun metodo integrato, ma potresti semplicemente usare linq:

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

5
Questo dovrebbe essere evitato se parameterListè già un elenco, poiché creerà inutilmente una nuova copia. In tal caso utilizzare il RemoveAllmetodo come altri suggeriscono.
Nick il

Questa è probabilmente l'opzione migliore se la raccolta è un file Array.
Andrew

25

Il metodo RemoveAll dovrebbe fare il trucco:

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

Perché non utilizzare la lambda?
Mike de Klerk

12
Questa è una risposta vecchia di quattro anni. All'epoca C # 3 era relativamente nuovo e stavo ancora usando C # 2 giorno per giorno. La sintassi lambda è ora la strada da percorrere; tuttavia, questa è ancora una risposta funzionante, quindi l'ho lasciata qui per chiunque non sia in grado di utilizzare la sintassi più recente (per qualsiasi motivo).
Mark Bell

2
Non ero a conoscenza del fatto che la sintassi lambda sia arrivata dopo. Grazie per la tua spiegazione! Senza dubbio è valido.
Mike de Klerk

8

Il metodo OfType()salterà i valori nulli:

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

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

In un certo senso, questo è un buon approccio, ma porta una sorpresa allo sviluppatore che pensa solo di OfTypeselezionare oggetti di un certo tipo, non pensando che non includerà nullvalori ... Quindi sono un po 'stanco di presentarlo nel mio codice.

@ BjörnAliGöransson d'accordo. È una soluzione interessante, ma non "legge" molto chiaramente. L'uso di .RemoveAll con un lambda mantiene comunque tutto su una singola riga, rendendo davvero ovvio ciò che lo sviluppatore che lo ha scritto stava cercando di ottenere. Tuttavia, questo potrebbe essere utile se c'è un vantaggio di velocità che vale la pena.
MattD

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

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

2

Facile e senza LINQ:

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

Questo metodo è in Listclasse proprio accanto a RemoveAll, quindi lo consiglierei per chiarezza. Se le prestazioni fossero cruciali, puoi seguire questo approccio (anche se rimuoverei le parentesi e probabilmente aggiungerei un commento per gli sviluppatori inconsapevoli).
Andrew

1
@Andrew: secondo MSDN, RemoveAll non accetta null. Penso di aver testato anche quello. Un commento ha senso però.
Tobias Knauss

1
RemoveAllricevuto un Predicate, quindi dovresti usare RemoveAll(x => x == null), come si vede nella risposta accettata e di Mark Bell.
Andrew

1

C'è un'altra opzione semplice ed elegante:

parameters.OfType<EmailParameterClass>();

Questo rimuoverà tutti gli elementi che non sono di tipo EmailParameterClass che ovviamente filtreranno tutti gli elementi di tipo null.

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

funzionerà? i riferimenti agli elementi non saranno ancora di tipo EmailParameterClasse avranno solo un valore uguale a null?
derHugo

Sicuramente lo farà e ho aggiunto un tester per il tuo intrattenimento.
Ryan Naccarato
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.