Concat 2 lists when one is null
Asked Answered
G

7

10

When both lists below on the line of code are populated my code works fine. However the error "Value cannot be null." occurs when LstNewItems is set to null. Why and how can i fix this or do i have to check if each list is null beforehand and act accordingly ?

this.radGridViewFiles.BeginInvoke((MethodInvoker)(
() => this.radGridViewFiles.DataSource = MyGlobals.ListOfItemsToControl
                                                  .Concat(MyGlobals.lstNewItems)
                                                  .ToList()
));
Greenleaf answered 31/1, 2014 at 21:53 Comment(3)
If at all possible, never let yourself be in the position where a list is null, so that you never need to check for null and handle that case any differently. Having an empty list instead of null is virtually always preferable.Pencil
Checking and acting accordingly would qualify as fixing it :-) However having null lists is a slight code smell IMO, perhaps it should be fixed at that level.Coax
@Pencil you are absolutely correct - i was setting the list to null where i should of had MyGlobals.lstNewItems.Clear() - thank you - do you want to put that in as an answer ?Greenleaf
P
9

If at all possible, never let yourself be in the position where a list is null, so that you never need to check for null and handle that case any differently. Having an empty list instead of null is virtually always preferable.

Pencil answered 1/2, 2014 at 2:0 Comment(3)
i was setting the list to null where i should of had MyGlobals.lstNewItems.Clear()Greenleaf
null can have different semantics to an empty list, this is not always a solution.Turino
@JurajFiala Of course they have different semantics. There would be no reason to advocate one over the other if they had identical semantics. While there are extremely rare situations where using null is appropriate for collections, as I said in my answer. This is not one of those situationsPencil
A
17

You can use

MyGlobals.lstNewItems ?? Enumerable.Empty<someObjectType>()
Assets answered 31/1, 2014 at 21:56 Comment(2)
And if it's a list of anonymous types ;)Pencil
can you be more specific to the line of code i need here ?Greenleaf
P
9

If at all possible, never let yourself be in the position where a list is null, so that you never need to check for null and handle that case any differently. Having an empty list instead of null is virtually always preferable.

Pencil answered 1/2, 2014 at 2:0 Comment(3)
i was setting the list to null where i should of had MyGlobals.lstNewItems.Clear()Greenleaf
null can have different semantics to an empty list, this is not always a solution.Turino
@JurajFiala Of course they have different semantics. There would be no reason to advocate one over the other if they had identical semantics. While there are extremely rare situations where using null is appropriate for collections, as I said in my answer. This is not one of those situationsPencil
L
8

For when you have any number of possibly null collections to concatenate:

IEnumerable<T> Concat<T>(params IEnumerable<T>[] nullableCollections)
{
    return nullableCollections.Where(nc => nc != null).SelectMany(nc => nc);
}

and later on you can call:

IEnumerable<T> allElements = Concat(myElements, yourElements, theirElements);

Without worrying if any of them are null.

Leavening answered 6/8, 2019 at 1:44 Comment(0)
T
6

What I do is create an extension method that can create an empty list if the enumeration is null:

public static IEnumerable<T> NeverNull<T>(this IEnumerable<T> value)
{
   return value ?? Enumerable.Empty<T>();
}

Then you can do:

this.radGridViewFiles.BeginInvoke((MethodInvoker)(
() => this.radGridViewFiles.DataSource = MyGlobals.ListOfItemsToControl
                                                  .Concat(MyGlobals.lstNewItems.NeverNull())
                                                  .ToList()
));

Example

Thrave answered 31/1, 2014 at 21:56 Comment(4)
This would throw an argument null exception just like the OP's code. You're calling DefaultIfEmpty on null.Pencil
@Pencil - Wrong. DefaultIfEmpty is, itself, an extension method so calling it on a null is perfectly fine. I use this code in several of my projects.Thrave
My mistake, you'll get another Argument Null Exception, not a NRE. So this will be equally problematic to the OP's code.Pencil
@Pencil - Totally screwed up, I meant Enumerable.Empty<> not .DefaultIfEmpty. That's what I get for writing this from memory rather than taking the 30 seconds to dig up my actual code.Thrave
C
4

Try this

 ( MyGlobals.ListOfItemsToControl ?? new List<Type>()).Concat(MyGlobals.lstNewItems ?? new List<Type>()) .ToList()
Constitutionalism answered 31/1, 2014 at 22:5 Comment(3)
Operator '??' cannot be applied to operands of type 'System.Collections.Generic.List<ValidState.ItemsUnderControlObject>' and 'System.Collections.Generic.List<System.Type>'Greenleaf
here Type will be the type of your item.for example if it is string than you should write ( MyGlobals.ListOfItemsToControl ?? new List<String>()) .Concat(MyGlobals.lstNewItems ?? new List<String>()) .ToList()Constitutionalism
Type in your case is ValidState.ItemsUnderControlObject then you should use ( MyGlobals.ListOfItemsToControl ?? new List<ValidState.ItemsUnderControlObject >()) .Concat(MyGlobals.lstNewItems ?? new List<ValidState.ItemsUnderControlObject >()) .ToList()Constitutionalism
S
1

Check for null before you concat. like,

if(MyGlobals.lstNewItems != null)
{
MyGlobals.ListOfItemsToControl.AddRange(MyGlobals.lstNewItems);
}
Spitz answered 31/1, 2014 at 22:0 Comment(0)
B
1

Try this:

public static IEnumerable<T> ConcatNull<T>(this IEnumerable<T> source, IEnumerable<T> value)
{
    return source != null ? source.Concat(value ?? Enumerable.Empty<T>()) : value ?? Enumerable.Empty<T>();
}

If both are null, you will get a non-null, empty enumerable. The expression check for null of the source parameter then concatenate a null-coalescing of the value parameter. If the source is null then it just returns null-coalescing of the value parameter.

Usage:

var result = collection1.ConcatNull(collection2);
Blakemore answered 25/11, 2023 at 0:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.