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.

Antworten:


225

Sie werden wahrscheinlich Folgendes wollen.

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

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

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

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

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

2

Einfach und ohne LINQ:

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

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

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.