Dealing with NULL collection in Linq query

D

Deckarep

Hey everyone,

Is there a more elegant or cleaner way of accomplishing the following
null check?


List<string> myString = null; //Purposely null list of strings to
show the example

XElement element = new XElement("Strings",
(myString != null) ?
(from string s in myString
where s.StartsWith("S")
select s) : null
);

This XElement yields the following result: <Strings/> and empty
Element.


I like that I can write linq to xml in nested declarations like this.
What I don't like now...is doing the null
check with the tertiary starts making the code ugly and less
readable. I know how to handle null values
when some of the contents in the collection may be null but what if
your collection is null itself??

If there's a better more Linq integrated way of handling this that
would be great.

Thanks,
 
J

Jeroen Mostert

Deckarep said:
Is there a more elegant or cleaner way of accomplishing the following
null check?


List<string> myString = null; //Purposely null list of strings to
show the example

XElement element = new XElement("Strings",
(myString != null) ?
(from string s in myString
where s.StartsWith("S")
select s) : null
);

This XElement yields the following result: <Strings/> and empty
Element.


I like that I can write linq to xml in nested declarations like this.
What I don't like now...is doing the null
check with the tertiary starts making the code ugly and less
readable. I know how to handle null values
when some of the contents in the collection may be null but what if
your collection is null itself??

If there's a better more Linq integrated way of handling this that
would be great.
Don't use null references for collections, use empty collections instead:

List<string> myString = new List<string>();

Edge case disappears. Also, a lambda is clearer here:

XElement element = new XElement(
"Strings",
myString.Where(s => s.StartsWith("S"))
);
 
G

Gilles Kohl [MVP]

Hey everyone,

Is there a more elegant or cleaner way of accomplishing the following
null check?


List<string> myString = null; //Purposely null list of strings to
show the example

XElement element = new XElement("Strings",
(myString != null) ?
(from string s in myString
where s.StartsWith("S")
select s) : null
);

This XElement yields the following result: <Strings/> and empty
Element.


I like that I can write linq to xml in nested declarations like this.
What I don't like now...is doing the null
check with the tertiary starts making the code ugly and less
readable. I know how to handle null values
when some of the contents in the collection may be null but what if
your collection is null itself??

If there's a better more Linq integrated way of handling this that
would be great.

Hmm, do you need to be able to differentiate between a null myString
and an empty list of strings?

That is, could you use List<string> myString = new List<string>();
and get rid of the tertiary?

Alternatively, something along these lines:

XElement element = new XElement("Strings",
(myString ?? new List<string>()).Where(s => s.StartsWith("S")));

Neither strike me as a lot cleaner or more elegant though :)

Regards,
Gilles.
 
D

Deckarep

Good point. I would use an empty collection if I could get away with
it. Unfortunately I'm using a system
that was not designed in this fashion so I often have to check for
null before knowing
if a collection is empty or not. :(

Thanks for the response tip on Lambda!
 
J

Jeroen Mostert

Deckarep said:
Good point. I would use an empty collection if I could get away with
it. Unfortunately I'm using a system
that was not designed in this fashion so I often have to check for
null before knowing
if a collection is empty or not. :(
If you really need to do this a lot, you can cheat your way around it:

public static class EnumerableExtensions {
public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T>
source) {
return source ?? Enumerable.Empty<T>();
}
}

Now

List<string> strings = null;
strings.EmptyIfNull().Where(s => s.StartsWith("S"));

will work.

Disclaimer: while neat, I have no idea if this is inefficient compared to
null checks and if so, exactly how much. Also, calling a method on a
reference that's notionally null is obviously a little counterintuitive, so
many people would just call this another abuse of extension methods. :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top