Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it better to use Enumerable.Empty<T>() as opposed to new List<T>() to initialize an IEnumerable<T>?

People also ask

What is enumerable empty?

IEnumerable<T> Enumerable. Empty<T>(); From MSDN: The Empty(TResult)() method caches an empty sequence of type TResult . When the object it returns is enumerated, it yields no elements.

Is IEnumerable faster than list C#?

IEnumerable is more efficient and faster when you only need to enumerate the data once. The List is more efficient when you need to enumerate the data multiple times because it already has all of it in memory.

How do I return an empty enumerable?

Empty<T> method returns an empty enumerable which doesn't yield any values when being enumerated. Enumerable. Empty<T> comes in very handy when you want to pass an empty to collection to a method accepting a parameter of type IEnumerable<T> . We can see that the returned sequence is an (empty) array of integers.


I think most postings missed the main point. Even if you use an empty array or empty list, those are objects and they are stored in memory. The Garbage Collector has to take care of them. If you are dealing with a high throughput application, it could be a noticeable impact.

Enumerable.Empty does not create an object per call thus putting less load on the GC.

If the code is in low-throughput location, then it boils down to aesthetic considerations though.


I think Enumerable.Empty<T> is better because it is more explicit: your code clearly indicates your intentions. It might also be a bit more efficient, but that's only a secondary advantage.


On the performance front, let's see how Enumerable.Empty<T> is implemented.

It returns EmptyEnumerable<T>.Instance, which is defined as:

internal class EmptyEnumerable<T>
{
    public static readonly T[] Instance = new T[0];
}

Static fields on generic types are allocated per generic type parameter. This means that the runtime can lazily create these empty arrays only for the types user code needs, and reuse the instances as many times as needed without adding any pressure on the garbage collector.

To wit:

Debug.Assert(ReferenceEquals(Enumerable.Empty<int>(), Enumerable.Empty<int>()));

Assuming you actually want to populate the Roles property somehow, then encapsulate that by making it's setter private and initialising it to a new list in the constructor:

public class Person
{
    public string Name { get; set; }
    public IList<Role> Roles { get; private set; }

    public Person()
    {
        Roles = new List<Role>();
    }
}

If you really really want to have the public setter, leave Roles with a value of null and avoid the object allocation.