Wie entferne ich alle Nullelemente in einer generischen Liste auf einmal?

112

Ist in .Net für C # eine Standardmethode definiert, mit der alle Elemente in einer Liste entfernt werden können null?

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

Angenommen, einige der Parameter sind null: Ich kann es nicht im Voraus wissen und möchte sie aus meiner Liste entfernen, damit sie nur Parameter enthält, die nicht null sind.

Bleistiftkuchen
quelle

Antworten:

225

Sie werden wahrscheinlich Folgendes wollen.

List<EmailParameterClass> parameterList = new List<EmailParameterClass>{param1, param2, param3...};
parameterList.RemoveAll(item => item == null);
Lanze
quelle
4
Ja, dies ist das gleiche wie meine Antwort, verwendet jedoch die neuere C # 3-Lambda-Syntax.
Mark Bell
@ Mark: Ich habe die geposteten Sekunden gesehen und Mann, es war knapp (32, 33 und 34). ;)
Lance
1
Ja ... nun, deine Antwort funktioniert auch in älteren Versionen, also +1! Also da, ha! ; Þ
Lance
43

Ich kenne keine eingebaute Methode, aber Sie könnten einfach linq verwenden:

parameterList = parameterList.Where(x => x != null).ToList();
Paul Hiles
quelle
5
Dies sollte vermieden werden, wenn parameterListes sich bereits um eine Liste handelt, da unnötigerweise eine neue Kopie erstellt wird. Verwenden Sie in diesem Fall die RemoveAllMethode, wie andere vorschlagen.
Nick
Dies ist wahrscheinlich die beste Option, wenn es sich bei der Sammlung um eine handelt Array.
Andrew
25

Die RemoveAll-Methode sollte den Trick machen:

parameterList.RemoveAll(delegate (object o) { return o == null; });
Mark Bell
quelle
Warum nicht das Lambda benutzen?
Mike de Klerk
12
Dies ist eine vier Jahre alte Antwort. Zu der Zeit war C # 3 relativ neu und ich benutzte C # 2 immer noch täglich. Die Lambda-Syntax ist jetzt der richtige Weg. Dies ist jedoch immer noch eine funktionierende Antwort, daher habe ich sie hier für alle belassen, die die neuere Syntax nicht verwenden können (aus welchem ​​Grund auch immer).
Mark Bell
2
Mir war nicht bewusst, dass die Lambda-Syntax später kam. Ich danke Ihnen für Ihre Erklärung! Ohne Zweifel ist es gültig.
Mike de Klerk
8

Die Methode OfType()überspringt die Nullwerte:

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

IList<EmailParameterClass> parameterList_notnull = 
    parameterList.OfType<EmailParameterClass>();
user3450075
quelle
In OfTypegewisser Weise ist dies ein guter Ansatz, aber es überrascht den Entwickler, der nur denkt, dass er Objekte eines bestimmten Typs auswählt, ohne zu glauben, dass er keine nullWerte enthält ... Ich bin also etwas müde, dies einzuführen in meinen eigenen Code.
@ BjörnAliGöransson Einverstanden. Es ist eine interessante Lösung, aber sie "liest" nicht sehr deutlich. Die Verwendung von .RemoveAll mit einem Lambda hält immer noch alles in einer einzigen Zeile und macht gleichzeitig deutlich, was der Entwickler, der es geschrieben hat, erreichen wollte. Dies kann jedoch nützlich sein, wenn sich ein Geschwindigkeitsvorteil lohnt.
MattD
4
List<EmailParameterClass> parameterList = new List<EmailParameterClass>{param1, param2, param3...};

parameterList = parameterList.Where(param => param != null).ToList();
Steve Danner
quelle
2

Einfach und ohne LINQ:

while (parameterList.Remove(null)) {};
Tobias Knauss
quelle
Diese Methode ist in der ListKlasse direkt neben RemoveAll, daher würde ich diese aus Gründen der Klarheit empfehlen. Wenn die Leistung entscheidend ist, können Sie diesen Ansatz wählen (obwohl ich die Klammern entfernen und wahrscheinlich einen Kommentar für ahnungslose Entwickler hinzufügen würde).
Andrew
1
@ Andrew: Laut MSDN nimmt RemoveAll nicht null an. Ich denke, ich habe das auch getestet. Ein Kommentar ist jedoch sinnvoll.
Tobias Knauss
1
RemoveAllerhielt eine Predicate, so sollten Sie verwenden RemoveAll(x => x == null), wie in der akzeptierten und Mark Bells Antwort zu sehen.
Andrew
1

Es gibt noch eine andere einfache und elegante Option:

parameters.OfType<EmailParameterClass>();

Dadurch werden alle Elemente entfernt, die nicht vom Typ sind, EmailParameterClasswodurch offensichtlich alle Elemente vom Typ herausgefiltert werden null.

Hier ist ein 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();
    }
}
Ryan Naccarato
quelle
Ob das funktioniert? Werden die Elementreferenzen nicht noch vom Typ sein EmailParameterClassund nur einen Wert gleich haben null?
derHugo
Es wird definitiv und ich habe Tester für Ihre Unterhaltung hinzugefügt.
Ryan Naccarato