I expected the implementation of Enumerable.Empty() to be just this:
public static IEnumerable<TResult> Empty<TResult>()
{
yield break;
}
But the implementation is something like this:
public static IEnumerable<TResult> Empty<TResult>()
{
return EmptyEnumerable<TResult>.Instance;
}
internal class EmptyEnumerable<TElement>
{
private static volatile TElement[] instance;
public static IEnumerable<TElement> Instance
{
get
{
if (EmptyEnumerable<TElement>.instance == null)
EmptyEnumerable<TElement>.instance = new TElement[0];
return (IEnumerable<TElement>)EmptyEnumerable<TElement>.instance;
}
}
}
Why does the implementation is more complex than just one line of code? Is there an advantage to return a cached array and not (yield) return no elements?
Note: I will never rely on the implementation details of a method, but I am just curious.
Compiling (using LINQpad with optimizations enabled)
results in quite a lot of code.
It will create a state machine that implements the
IEnumerable
interface. Every time you callMyEmpty
it will create a new instance of that class. Returning the same instance of an empty array is quite cheap.The IL code for
EmptyEnumerable
is:And for the
MyEmpty
method it is: