Bagaimana cara menghapus semua elemen null di dalam daftar generik sekaligus?

112

Apakah ada metode default yang ditentukan dalam .Net untuk C # untuk menghapus semua elemen dalam daftar yang mana null?

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

Katakanlah beberapa parameter adalah null; Saya tidak dapat mengetahui sebelumnya dan saya ingin menghapusnya dari daftar saya sehingga hanya berisi parameter yang bukan null.

pencilCake
sumber

Jawaban:

225

Anda mungkin menginginkan yang berikut ini.

List<EmailParameterClass> parameterList = new List<EmailParameterClass>{param1, param2, param3...};
parameterList.RemoveAll(item => item == null);
Tombak
sumber
4
Ya, ini sama dengan jawaban saya tetapi menggunakan sintaks lambda C # 3 yang lebih baru.
Mark Bell
@ Mark: Saya melihat detik yang diposting dan pria itu dekat (32, 33, dan 34). ;)
Lance
1
Ya ... jawaban Anda berfungsi bahkan di versi yang lebih lama jadi +1! Jadi di sana, ha! ; Þ
Lance
43

Saya tidak tahu metode bawaan apa pun, tetapi Anda bisa menggunakan linq:

parameterList = parameterList.Where(x => x != null).ToList();
Paul Hiles
sumber
5
Ini harus dihindari jika parameterListsudah menjadi List, karena tidak perlu membuat salinan baru. Dalam hal ini gunakan RemoveAllmetode seperti yang disarankan orang lain.
Nick
Ini mungkin pilihan terbaik jika koleksinya adalah Array.
Andrew
25

Metode RemoveAll harus melakukan trik:

parameterList.RemoveAll(delegate (object o) { return o == null; });
Mark Bell
sumber
Mengapa tidak menggunakan lambda?
Mike de Klerk
12
Ini adalah jawaban berusia empat tahun. Saat itu C # 3 relatif baru, dan saya masih menggunakan C # 2 sehari-hari. Sintaks lambda sekarang adalah cara yang harus dilakukan; Namun, ini masih merupakan jawaban yang berfungsi, jadi saya meninggalkannya di sini untuk siapa pun yang tidak dapat menggunakan sintaks yang lebih baru (untuk alasan apa pun).
Mark Bell
2
Saya tidak menyadari bahwa sintaks lambda datang kemudian. Terima kasih atas penjelasan Anda! Tanpa diragukan lagi ini valid.
Mike de Klerk
8

Metode ini OfType()akan melewatkan nilai null:

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

IList<EmailParameterClass> parameterList_notnull = 
    parameterList.OfType<EmailParameterClass>();
pengguna3450075
sumber
Di satu sisi, ini adalah pendekatan yang baik, tetapi ini membawa kejutan bagi pengembang yang hanya berpikir bahwa OfTypememilih objek dari tipe tertentu, tidak berpikir bahwa itu tidak akan menyertakan nullnilai ... Jadi saya agak lelah untuk memperkenalkan ini ke dalam kode saya sendiri.
@ BjörnAliGöransson Setuju. Ini solusi yang menarik, tetapi tidak "terbaca" dengan sangat jelas. Menggunakan .RemoveAll dengan lambda tetap menyimpan semuanya dalam satu baris sekaligus membuatnya sangat jelas tentang apa yang ingin dicapai oleh pengembang yang menulisnya. Namun, ini mungkin berguna jika ada manfaat kecepatan yang bermanfaat.
MattD
4
List<EmailParameterClass> parameterList = new List<EmailParameterClass>{param1, param2, param3...};

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

Mudah dan tanpa LINQ:

while (parameterList.Remove(null)) {};
Tobias Knauss
sumber
Metode itu ada di Listkelas di sebelahnya RemoveAll, jadi saya akan merekomendasikan yang satu untuk kejelasan. Jika kinerja ternyata sangat penting, maka Anda dapat menggunakan pendekatan ini (meskipun saya akan menghapus tanda kurung dan mungkin menambahkan komentar untuk pengembang yang tidak sadar).
Andrew
1
@ Andrew: menurut MSDN, RemoveAll tidak mengambil null. Saya rasa saya juga telah mengujinya. Sebuah komentar masuk akal.
Tobias Knauss
1
RemoveAllmenerima Predicate, jadi Anda harus menggunakan RemoveAll(x => x == null), seperti yang terlihat dalam jawaban diterima dan Mark Bell.
Andrew
1

Ada opsi sederhana dan elegan lainnya:

parameters.OfType<EmailParameterClass>();

Ini akan menghapus semua elemen yang bukan tipe EmailParameterClassyang jelas akan menyaring elemen tipe apa pun null.

Berikut tesnya:

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
sumber
apakah ini akan berhasil? tidak akan referensi elemen masih berjenis EmailParameterClassdan hanya memiliki nilai yang sama dengan null?
derHugo
Itu pasti akan dan saya menambahkan penguji untuk hiburan Anda.
Ryan Naccarato