Empty Arrays

« Equality Testing in NUnit | Main | Colors Undocumented »

February 20, 2004

Empty Arrays

Microsoft guidelines recommend developers to avoid using nulls for returning arrays or strings inside managed code. Instead, the empty string should be returned for strings, and an empty array should be returned for arrays.

Benefits
There are several benefits to following the guidelines.

  1. Reliability. The avoidance of nulls eliminates the possibility of a NullReferenceException being raised, potentially bringing an application down to a halt. Usually, most code will continue to work correctly if presented with an empty array or string, since a length of zero follows a continuous programming model for dealing with exceptional cases; however, null references must always be explicitly handled.
  2. Simplicity and conciseness. The use of two different values, a null value and an empty value, for exceptional results often requires that multiple checks be performed and that code be written to handle both cases similarly. This may also result in inconsistent return values from similar functions or even the same function over time. If one of the two checks is missed, hopefully not the wrong one, then it may be possible for the two return values to follow different code paths, which can be problematic for testing.
  3. Consistency. The two different values can also lead to confusion as to which value is returned when a method returns an array. For example, the .NET framework has Type.GetProperties() that returns an array of PropertyInfo[], but the documentation does not indicate what value is returned in the event of no properties. Standardizing on return values of empty arrays, as the framework has done, allows the developer to accurately predict the result of a method call in the absence of adequate documentation, especially when cases where a method would return an exceptional result are rare (thus preventing the experimental determination of the exceptional return value).

Reducing the Memory Hit
Standardizing on empty arrays and strings offers more reliable and concise code. However, the tradeoff is introduction of additional memory allocations and the greater frequency of garbage collection. The tradeoff is actually minimal, since temporary allocations are almost free.

For strings, memory allocation is easily avoided by calling String.Empty or even by using the literal empty string "", which is guaranteed to be interned. For empty arrays, the solution to the memory allocation issue is surprisingly simple: Empty arrays are not modifiable, since they have no elements. As a result, they can be shared freely! A static variable can thus be declared, pointing to an empty array of a given type, such as the following:

public static object [] EmptyArray = new object[0];
public static string [] EmptyStringArray = new string[0];

Note that an empty array still needs to be declared for each type. Through the magic of covariance, you can get away with returning an array of a derived type for a function that is declared to return an array of a base type. For example, EmptyStringArray, an empty string array can be returned wherever an object array is expected.

One last point: The Whidbey string class does support a new method IsNullOrEmpty which performs a check for both the null and empty string, so while Microsoft recommends strictly relying on the empty string, it is being pragmatic by providing support for a common but deprecated usage pattern.


Comments