144

Is there a default method defined in .Net for C# to remove all the elements within a list which are null?

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

Let's say some of the parameters are null; I cannot know in advance and I want to remove them from my list so that it only contains parameters which are not null.

Mark Bell
  • 28,985
  • 26
  • 118
  • 145
pencilCake
  • 51,323
  • 85
  • 226
  • 363

7 Answers7

281

You'll probably want the following.

List<EmailParameterClass> parameterList = new List<EmailParameterClass>{param1, param2, param3...};
parameterList.RemoveAll(item => item == null);
Lance
  • 5,655
  • 4
  • 30
  • 32
61

I do not know of any in-built method, but you could just use linq:

parameterList = parameterList.Where(x => x != null).ToList();
Paul Hiles
  • 9,558
  • 7
  • 51
  • 76
  • 13
    This should be avoided if `parameterList` is already a List, as it will unnecessarily create a new copy. In that case use the `RemoveAll` method as others suggest. – Nick Jun 30 '16 at 17:36
  • 1
    This is probably the best option if the collection is an `Array`. – Andrew Jul 15 '16 at 09:00
29

The RemoveAll method should do the trick:

parameterList.RemoveAll(delegate (object o) { return o == null; });
Mark Bell
  • 28,985
  • 26
  • 118
  • 145
  • Why not use the lambda? – Mike de Klerk Nov 04 '14 at 14:16
  • 16
    This is a four year old answer. At the time C# 3 was relatively new, and I was still using C# 2 day-to-day. The lambda syntax is now the way to go; however, this is still a working answer, so I've left it here for anyone unable to use the newer syntax (for whatever reason). – Mark Bell Nov 04 '14 at 15:54
  • 2
    I wasn't aware that the lambda syntax came later. Thank you for your explanation! Without a doubt it is valid. – Mike de Klerk Nov 06 '14 at 09:45
11

There is another simple and elegant option:

parameters.OfType<EmailParameterClass>();

This will remove all elements that are not of type EmailParameterClass which will obviously filter out any elements of type null.

Here's a test:

class Program
{
    class Test { }

    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
  • 674
  • 8
  • 12
  • will this work? won't be the element references still of type `EmailParameterClass` and only have a value equal to `null`? – derHugo Jan 13 '20 at 13:32
  • It definitely will and i added tester for your entertainment. – Ryan Naccarato Jan 31 '20 at 22:19
  • This is great, especially when using nullable annotations because it not only filters out the nulls, but force-casts it to a non-nullable type (e.g. `Bitmap?[]` becomes `Bitmap[]`) – Mark A. Donohoe Oct 28 '20 at 05:11
10

The method OfType() will skip the null values:

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

IList<EmailParameterClass> parameterList_notnull = 
    parameterList.OfType<EmailParameterClass>();
Shnugo
  • 66,100
  • 9
  • 53
  • 114
user3450075
  • 121
  • 1
  • 4
  • 2
    In a way, this is a good approach, but it brings a surprise to the developer who just thinks that `OfType` selects objects of a certain type, not thinking that it will not include `null` values ... So I'm a bit weary to introduce this into my own code. –  Apr 12 '16 at 21:14
  • 1
    @BjörnAliGöransson Agreed. It's an interesting solution, but it doesn't "read" very clearly. Using .RemoveAll with a lambda still keeps everything on a single line while making it really obvious as to what the developer who wrote it was trying to achieve. However, this might be useful if there's a speed benefit that's worthwhile. – MattD Jun 09 '16 at 20:59
  • The cool thing about this solution is, that it will change the generic parameter from T? to T. – Tim Pohlmann Jun 15 '21 at 22:15
4
List<EmailParameterClass> parameterList = new List<EmailParameterClass>{param1, param2, param3...};

parameterList = parameterList.Where(param => param != null).ToList();
Steve Danner
  • 21,818
  • 7
  • 41
  • 51
3

Easy and without LINQ:

while (parameterList.Remove(null)) {};
Tobias Knauss
  • 3,361
  • 1
  • 21
  • 45
  • That method is in `List` class just next to `RemoveAll`, so I'd recommend that one for clarity. If performance happened to be crucial, then you can go with this approach (although I'd remove the brackets and probably add a comment for unaware developers). – Andrew Jul 15 '16 at 09:14
  • 1
    @Andrew: according to MSDN, RemoveAll does not take null. I think I also have tested that. A comment makes sense though. – Tobias Knauss Jul 17 '16 at 11:25
  • 1
    `RemoveAll` received a `Predicate`, so you should use `RemoveAll(x => x == null)`, as seen in the accepted and Mark Bell's answer. – Andrew Jul 17 '16 at 12:10