52

When I type the following code:

object[] objects = new object[] { };

Visual Studio tells me:

Avoid unnecessary zero-length allocations. Use Array.Empty<object>() instead.

Are there any actual implications of using one over the other?

What is the reason for the warning?

MarredCheese
  • 17,541
  • 8
  • 92
  • 91
Mike Cheel
  • 12,626
  • 10
  • 72
  • 101
  • 4
    Hm, well every call to `Array.Empty()` returns the same array, whereas your code will create multiple arrays. It might be to avoid unnecessary overhead. –  Oct 30 '18 at 19:01
  • 4
    You're creating something you don't need to create. Array.Empty references a static readonly property, so there is only one instance within the appdomain. –  Oct 30 '18 at 19:01
  • @Will Kindly put that as an answer. – Mike Cheel Oct 30 '18 at 19:02
  • Some points mentioned for [Should I use string.Empty or String.Empty or “” to intitialize a string?](https://stackoverflow.com/q/263191/205233) may also apply. – Filburt Oct 30 '18 at 19:05
  • @MikeCheel take a look at this link: http://justinvp.com/2015/07/20/array-empty/ – Zinov Oct 30 '18 at 19:06
  • 4
    If Visual Studio can detect this and generate a warning, why can't the compiler fix it? – Joe Oct 30 '18 at 19:13
  • 2
    @Joe I'm guessing here but there maybe times when you want multiple empty arrays. – Mike Cheel Oct 30 '18 at 19:14
  • see https://stackoverflow.com/questions/8727146/how-do-i-initialize-an-empty-array-in-c – juFo Dec 05 '19 at 09:21

2 Answers2

81

You're creating an empty array. Which will always be empty, as you cannot change the capacity of the array instance (it just sounds weird to say you can't change its length, I don't know, why). Every time you do this, you create another instance of an array that can never be used. Doing this a lot may result in wasted GC and memory pressure, thus the warning.

Instead of creating empty arrays, just use Array.Empty<T>() as it suggests. This method returns an array using this static class

internal static class EmptyArray<T>
{
    public readonly static T[] Value;

    static EmptyArray()
    {
        EmptyArray<T>.Value = new T[0];
    }
}

Since it's static and readonly, there's only ever one instance of this empty array in the entire app domain. An empty array is essentially immutable, so caching the instance isn't a problem. And it allows you to forego special-casing empty array creation in your algorithms if you find yourself eyeballing an elegant code path that is creating tons of empty arrays.

Enumerable.Empty<T>() is the Linq to Objects equivalent and is also useful for not wasting allocations for empty stuff.

MarredCheese
  • 17,541
  • 8
  • 92
  • 91
  • 2
    this is interesting! i didnt realize that the class is `static` and `readonly` and it will only create one instance of the empty array...made me think about the disaster under the hood in the huge application my team has been working on. its a shame that visual studio does not provide a reason for its fix...! – Niklas Oct 06 '19 at 09:29
9

Using Array.Empty is useful to avoid unnecessary memory allocation. Refer the code from .NET Library itself below:

[Pure]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public static T[] Empty<T>()
{
    Contract.Ensures(Contract.Result<T[]>() != null);
    Contract.Ensures(Contract.Result<T[]>().Length == 0);
    Contract.EndContractBlock();

    return EmptyArray<T>.Value;
}
...
// Useful in number of places that return an empty byte array to avoid unnecessary memory allocation.
internal static class EmptyArray<T>
{
    public static readonly T[] Value = new T[0];
}

Source: https://referencesource.microsoft.com/#mscorlib/system/array.cs,bc9fd1be0e4f4e70

adityap
  • 329
  • 1
  • 10
  • I want to add a comment on Code Contracts, as they are not supported in .NET 5+ (https://learn.microsoft.com/en-us/dotnet/framework/debug-trace-profile/code-contracts) – GLJ Mar 06 '23 at 19:04