Як видалити всі нульові елементи всередині загального списку за один раз?


112

Чи визначений метод за замовчуванням, визначений у .Net для C #, щоб видалити всі елементи зі списку, які є null?

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

Скажімо, деякі параметри є null; Я не можу знати заздалегідь, і я хочу видалити їх зі свого списку, щоб він містив лише параметри, які не є нульовими.

Відповіді:


225

Напевно, ви захочете наступного.

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

4
Так, це те саме, що і моя відповідь, але використовуючи новіший синтаксис лямбда C # 3.
Марк Белл

@Mark: Я побачив розміщені секунди і людину, яка була поруч (32, 33 та 34). ;)
Ленс

1
Так ... добре, що ваша відповідь працює навіть у старих версіях, тому +1! Так що, га! ; Þ
Ланс

43

Я не знаю жодного вбудованого методу, але ви можете просто використовувати linq:

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

5
Цього слід уникати, якщо parameterListвже є Список, оскільки це зайво створить нову копію. У такому випадку використовуйте RemoveAllметод, як пропонують інші.
Нік

Це, мабуть, найкращий варіант, якщо колекція є Array.
Андрій

25

Метод RemoveAll повинен зробити фокус:

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

Чому б не використовувати лямбда?
Майк де Клерк

12
Це чотирирічна відповідь. На той час C # 3 був відносно новим, і я все ще використовував C # 2 щодня. Синтаксис лямбда зараз - це шлях; проте це все ще справна відповідь, тому я залишив її тут для тих, хто не може використовувати новіший синтаксис (з будь-якої причини).
Марк Белл

2
Я не усвідомлював, що синтаксис лямбда з’явився пізніше. Дякую за ваше пояснення! Без сумніву, це дійсно.
Майк де Клерк

8

Метод OfType()буде пропускати нульові значення:

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

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

Зрештою, це хороший підхід, але він приносить сюрприз розробнику, який просто думає, що OfTypeвибирає об'єкти певного типу, не думаючи, що він не буде включати nullзначення ... Тому я трохи втомився вводити це в мій власний код.

@ BjörnAliGöransson Погодився. Це цікаве рішення, але воно не «читається» дуже чітко. Використання .RemoveAll з лямбда все ще тримає все в одному рядку, роблячи дійсно очевидним, що намагався досягти розробник, який написав це. Однак це може бути корисним, якщо є корисна швидкість, яка варта.
MattD

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

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

2

Легко і без LINQ:

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

Цей метод знаходиться в Listкласі безпосередньо поруч RemoveAll, тому я рекомендував би його для наочності. Якщо продуктивність виявилася вирішальною, тоді ви можете піти з таким підходом (хоча я б зняв дужки і, мабуть, додав коментар для необізнаних розробників).
Андрій

1
@Andrew: згідно з MSDN, RemoveAll не приймає null. Я думаю, що я теж це перевірив. Хоча коментар має сенс.
Тобіас Кнаусс

1
RemoveAllотримав а Predicate, тож вам слід скористатися RemoveAll(x => x == null), як видно з прийнятої та відповіді Марка Белла.
Андрій

1

Є ще один простий і елегантний варіант:

parameters.OfType<EmailParameterClass>();

Це видалить усі елементи, які не є типовими, EmailParameterClassякі, очевидно, відфільтрують будь-які елементи типу null.

Ось тест:

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

це буде працювати? не будуть посиланнями на елементи все ще типу EmailParameterClassі мають лише значення, рівне null?
derHugo

Це безумовно, і я додав тестер для вашої розваги.
Райан Наккарато
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.