2

I find myself writing the following over and over:

if (myEnumerable != null) {
    foreach (var element in myEnumerable) {
        DoSomething(element);
    }
}

It's tedious to check for NULL every time I want to enumerate, is there a better way? For instance, is there a way to override the enumerator to return "Enumerable.Empty" instead of NULL?

desautelsj
  • 3,587
  • 4
  • 37
  • 55
  • Better in what sense? I don't see what you are trying to improve here. – Tudor Jan 08 '12 at 20:03
  • Why do you iterate over potentially null sequences so often in the first place? I almost never need to check for null before looping, because in most cases `null` is an invalid argument to my function in the first place, and validated as such. – CodesInChaos Jan 08 '12 at 20:05

4 Answers4

8

You could use the null-coalescing operator:

foreach (var element in myEnumerable ?? Enumerable.Empty<Foo>()) {
    DoSomething(element);
}

but a much better way is to ensure that wherever you are fetching this IEnumerable<T> from never returns null which is the conventional way to work with enumerables in .NET.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Very good suggestion. Can we take it one step further: do you think we could override the enumerator and return "empty" instead of null? – desautelsj Jan 08 '12 at 20:04
  • 2
    @desautelsj, no, for me, the step further is to fix the code returning this enumerable so that it never returns null. – Darin Dimitrov Jan 08 '12 at 20:06
  • @desautelsj: Override *which* enumerator? You're talking about a variable which is null to start with - you just can't call anything other than extension methods on that. We have no idea what's returning the null reference to start with. – Jon Skeet Jan 08 '12 at 20:06
6

Well, ideally design your code so that it can't be null. Alternatively, create an extension method:

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

Then:

foreach (var element in myEnumerable.EmptyIfNull())
    DoSomething(element);
}

This is much the same as Darin's approach, but moves the null coalescing operator into an extension method.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    What's `T` in `T[] EmptyArray = ...`? – dtb Jan 08 '12 at 20:04
  • Of course this can significantly reduce enumeration speed if the static type of the sequence you work on is different from `IEnumerable`. – CodesInChaos Jan 08 '12 at 20:07
  • @CodeInChaos: Well, to be *significant* we'd have to assume that `DoSomething` is pretty trivial. But yes, in the pretty unusual situation that you've got a compile-time type of `List`, the variable can be null, you're going to do a *lot* of iterations in the normal case, and the work for each iteration is very small... in that case it could have a significant impact. Try to avoid such situations. – Jon Skeet Jan 08 '12 at 20:09
1

An extension method:

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

Then you can do

foreach (var element in myEnumerable.EmptyIfNull())
{
  DoSomething(element);
}
Anders Abel
  • 67,989
  • 17
  • 150
  • 217
0

Unfortunately checking for null is a fact of life...but it can be easier. I have written an extension named ValidWithItems to check for null as well as divining when not null there are items to actually enumerate.

public static class EnumerableExtensions
{

    /// <summary>Does two checks, if not null and if it has items.</summary>
    /// <returns>True if it is not null and has at least 1 item.</returns>
    public static bool ValidWithItems<T>( this IEnumerable<T> target )
    {
        return ((target != null) && (target.Any()));
    }
}
ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122