10

I'm dealing with some arrays that are being returned to me from a 3rd party API. Sometimes these come back as null. I am able to handle everything elegantly with LINQ except for the null case. I came up with something like this:

IEnumerable<Thing> procs = APICall(foo, bar);
var result = from proc in procs ?? Enumerable.Empty<Thing>()
    where proc != null
    select Transform(proc);

The use of the coalescing operator here chafes a little. Am I missing something from LINQ that handles this?

recursive
  • 83,943
  • 34
  • 151
  • 241
  • Possible duplicate of [C# EmptyIfNull extension for any IEnumerable to return empty derived type](http://stackoverflow.com/questions/34645963/c-sharp-emptyifnull-extension-for-any-ienumerable-to-return-empty-derived-type) – Michael Freidgeim Oct 26 '16 at 07:20
  • How can a question asked in 2011 be a duplicate of one asked in 2016? – recursive Oct 26 '16 at 14:26

4 Answers4

13

This is in effect the same solution that you have, but I use an extension method.

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

So that we end up with:

IEnumerable<Thing> procs = APICall(foo, bar);
var result = from proc in procs.EmptyIfNull()
             where proc != null
             select Transform(proc);
Reddog
  • 15,219
  • 3
  • 51
  • 63
  • Answer http://stackoverflow.com/questions/34645963/c-sharp-emptyifnull-extension-for-any-ienumerable-to-return-empty-derived-type/34646103#34646103 has different overloads for list/array/IEnumerable – Michael Freidgeim Oct 26 '16 at 07:21
2

You could just write the following:

IEnumerable<Thing> procs = APICall(foo, bar) ?? Enumerable.Empty<Thing>();

var result = from proc in procs
    where proc != null
    select Transform(proc);

This way you move the coalescing outside the linq expression which makes the code look more tight.

You could also just skip the linq expression entirely by doing an conditional check on nonnull.

Simon Stender Boisen
  • 3,413
  • 20
  • 23
1

why not use something more efficient like:

IEnumerable<Thing> procs = APICall(foo, bar);
IEnumerable<Transform> result = null;
if(procs != null)
    result = from proc in procs ?? Enumerable.Empty<Thing>()
         where proc != null
         select Transform(proc);
Reddog
  • 15,219
  • 3
  • 51
  • 63
  • 1
    `IEnumerable` is not likely valid. `Transform(proc)` is a *method call*, not a *constructor*. What it returns is only known to the OP at the moment. I recommend a `IEnumerable` placeholder. – Anthony Pegram May 24 '11 at 19:18
  • 2
    The OP's original code will always have a result referencing an object, but this code leaves it possibly null. And if you are checking if `procs` is null or not, the coalesce isn't necessary. – Matt Greer May 24 '11 at 19:18
0

Linq expects an ienumerable of something, even if it is empty. Perhaps you can try moving the coalescing to after the api call?

Jay
  • 6,224
  • 4
  • 20
  • 23