100

In C# I use LINQ and IEnumerable a good bit. And all is well-and-good (or at least mostly so).

However, in many cases I find myself that I need an empty IEnumerable<X> as a default. That is, I would like

for (var x in xs) { ... }

to work without needing a null-check. Now this is what I currently do, depending upon the larger context:

var xs = f() ?? new X[0];              // when xs is assigned, sometimes
for (var x in xs ?? new X[0]) { ... }  // inline, sometimes

Now, while the above is perfectly fine for me -- that is, if there is any "extra overhead" with creating the array object I just don't care -- I was wondering:

Is there "empty immutable IEnumerable/IList" singleton in C#/.NET? (And, even if not, is there a "better" way to handle the case described above?)

Java has Collections.EMPTY_LIST immutable singleton -- "well-typed" via Collections.emptyList<T>() -- which serves this purpose, although I am not sure if a similar concept could even work in C# because generics are handled differently.

Thanks.

  • Well, darn :) This is what I get for focusing on List/IList and not Enumerable/IEnumerable, thanks all -- votes all around. –  Dec 19 '11 at 00:09
  • http://stackoverflow.com/questions/3229698/how-can-i-return-an-empty-ienumerable –  Dec 19 '11 at 00:22
  • 2
    `public static class Array { public static readonly T[] Empty = new T[0]; }` and it can be called like: `Array.Empty`. I asked about it [here in CodeReview](http://codereview.stackexchange.com/q/20417/17039). – Şafak Gür Jan 15 '13 at 10:44

7 Answers7

113

You are looking for Enumerable.Empty<T>().

In other news the Java empty list sucks because the List interface exposes methods for adding elements to the list which throw exceptions.

Alexander Oh
  • 24,223
  • 14
  • 73
  • 76
Stilgar
  • 22,354
  • 14
  • 64
  • 101
  • That's a very valid point! Perhaps it warrants a new SO question? –  Dec 19 '11 at 00:17
  • 1
    You were a few seconds slow and no documentation link _*finger shake*_ ;-) But the accept for expanding upon svicks comment. –  Dec 19 '11 at 00:20
  • Also the other guys got more upvotes so we're even:) I would post a question but I'm going to bed right now and I won't be able to follow the question. Why not post it yourself? – Stilgar Dec 19 '11 at 00:32
  • 36
    Because a class method may need to return a `List` (a collection that can be accessed by index). Those `List` can be readonly. And sometime you need to return such a readonly `List` with zero element in it. Thus, the `Collections.emptyList()` method. You can't just return an empty Iterable because an implemented interface specify that the method return a list. The big problem is that their is no ImmutableList interface that you can return. The same problem exist in .NET : any `IList` may well be readonly. – Laurent Bourgault-Roy Nov 30 '12 at 06:59
  • 6
    On a side note, every array is a IList in C#, and this will throw when you try to add new items as well. – Grzenio Jan 27 '14 at 16:47
  • function shouldIUseList(readOnlyMethodsINeed){ return (setOfListMethods() - setOfIterableMethods()).containsAny(readOnlyMethodsINeed); } – Rodrigo Quesada Sep 23 '16 at 05:04
  • Throwing exceptions vs read-only interface ~= getting error at runtime vs getting it at compile-time. I would definitely prefer Java spec to define a read-only interface for lists, but that's unfortunately not the case. – Rodrigo Quesada Sep 23 '16 at 05:10
  • 2
    To whom it may concern: Very often, the reason for wanting some kind of list (rather than `IEnumerable`) is its property of being materialized (no deferred execution) and having a known `Count`. In this case, we should use `IReadOnlyCollection`. If indexed access is also required, there is `IReadOnlyList`. – Timo Jul 09 '18 at 10:00
57

Enumerable.Empty<T>() is exactly that.

Jon
  • 428,835
  • 81
  • 738
  • 806
  • 8
    Well, not *exactly*. :) Since a "list" was asked for, `Array.Empty()` is more accurate, as it is an `IList`. It has the happy benefit of also satisfying `IReadOnlyCollection`. Of course, where an `IEnumerable` *does* suffice, `Enumerable.Empty()` fits perfectly. – Timo Jul 09 '18 at 09:55
  • 4
    @Timo this question, and many of the answers including this one, were written roughly 3 years before `Array.Empty` was made available. :) In any case, the title notwithstanding, the question makes it explicitly clear that an `IEnumerable` is good for the purpose. – Jon Jul 09 '18 at 21:50
22

In your original example you use an empty array to provide an empty enumerable. While using Enumerable.Empty<T>() is perfectly right, there might other cases: if you have to use an array (or the IList<T> interface), you can use the method

System.Array.Empty<T>()

which helps you to avoid unnecessary allocations.

Notes / References:

ventiseis
  • 3,029
  • 11
  • 32
  • 49
  • Thanks for pointing out the documentation is out of line with roslyn analyzers. Did you ever open an issue on GitHub to correct that? – John Zabroski Jan 11 '21 at 18:48
20

I think you're looking for Enumerable.Empty<T>().

Empty list singleton doesn't make that much sense, because lists are often mutable.

svick
  • 236,525
  • 50
  • 385
  • 514
10

I think adding an extension method is a clean alternative thanks to their ability to handle nulls - something like:

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

  foreach(var x in xs.EmptyIfNull())
  {
    ...
  }
Andrew Hanlon
  • 7,271
  • 4
  • 33
  • 53
2

Using Enumerable.Empty<T>() with lists has a drawback. If you hand Enumerable.Empty<T> into the list constructor then an array of size 4 is allocated. But if you hand an empty Collection into the list constructor then no allocation occurs. So if you use this solution throughout your code then most likely one of the IEnumerables will be used to construct a list, resulting in unnecessary allocations.

Nathan Tuggy
  • 2,237
  • 27
  • 30
  • 38
sjb-sjb
  • 1,112
  • 6
  • 14
  • why would you ever pass `Enumerable.Empty()` into a constructor for a `List`? That makes no sense to me. The point of `Enumerable.Empty()` is to avoid having to initialize empty `List` instances where you need an empty and non-null instance. – Dave Black Jan 13 '22 at 22:57
  • Since this answer is newer than 2015, it could mention `Array.Empty()` which came with .NET Framework 4.6 from 2015. This is useful if you need an empty (preallocated and immutable) instance of compile-time type `T[]`, `IReadOnlyList`, `IReadOnlyCollection`, `IList`, `ICollection` and so on. – Jeppe Stig Nielsen Feb 27 '23 at 17:31
1

Microsoft implemented `Any()' like this (source)

public static bool Any<TSource>(this IEnumerable<TSource> source)
{
    if (source == null) throw new ArgumentNullException("source");
    using (IEnumerator<TSource> e = source.GetEnumerator())
    {
        if (e.MoveNext()) return true;
    }
    return false;
}

If you want to save a call on the call stack, instead of writing an extension method that calls !Any(), just rewrite make these three changes:

public static bool IsEmpty<TSource>(this IEnumerable<TSource> source) //first change (name)
{
    if (source == null) throw new ArgumentNullException("source");
    using (IEnumerator<TSource> e = source.GetEnumerator())
    {
        if (e.MoveNext()) return false; //second change
    }
    return true; //third change
}
user2023861
  • 8,030
  • 9
  • 57
  • 86