Code Housekeeping refers to general rules of thumb that make code easier to read, digest, and modify for other developers, yourself included.

In today’s post, we will look at a common problem with collections.

Let us take our usual example, a domain model with the following types - a Spy, defined thus:

public sealed class Spy
{
  public required string FirstName { get; init; }
  public required string Surname { get; init; }
  public required DateOnly DateOfBirth { get; init; }
}

And an Agency, defined thus:

public sealed class Agency
{
  public required string Name { get; init; }
  public required Spy[] Spies { get; init; }
}

Suppose we want to create a new Agency that does not presently have any Spy.

One way would be to do it this way:

var agency = new Agency()
{
  Name = "Savak",
  Spies = null
};

This works, but it is a problem waiting for you downstream.

Suppose later in the program we wrote this code:

//
// Later
//

// List all the spies in this agency
foreach (var spy in agency.Spies)
{
    Console.WriteLine($"{spy.FirstName} {spy.Surname}");
}

Running this program will throw a NullReferenceException.

Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
   at Program.<Main>$(String[] args) in /Users/rad/Projects/BlogCode/EmptyCollections/Program.cs:line 12

The solution to this is to initialize the Spies collection to an empty collection.

This can be done in several ways:

var agency2 = new Agency()
{
    Name = "Savak",
    Spies = Array.Empty<Spy>()
};

A better way to do this is as follows:

var agency2 = new Agency()
{
    Name = "Savak",
    Spies = []
};

This is using the collection expression syntax, which, besides being terse, means that if you change the collection type to something else, like a list, your initialization code does not need to change.

If you are using a traditional class without the required and init modifiers, define it like this:

public sealed class Agency
{
    public string Name { get; set; }
    public Spy[] Spies { get; set; } = [];
}

This way, if the user forgets to initialize the collection, it is always a safe empty collection.

TLDR

Do not return NULL in the place of empty collections.

The code is in my GitHub.

Happy hacking!