Ordering of static fields in C# matters

3 Written by Bill Boga

This post is days old.

I never thought ordering of relational static fields and properties in C# mattered. And, then, I started getting NREs on a property I know was set to a static-instance…

The setup

public static void Main () { Console . WriteLine ( Person . Empty == null ); // prints 'True' } public class Person { public static readonly Person Empty = empty ; private static readonly EmptyPerson empty = new EmptyPerson (); } public sealed class EmptyPerson : Person { }

If you were to step-through the code, the first-time Person.Empty is called, empty is null and gets returned as-is. Then, empty is initialized. But, it’s too late since Empty is static and will only get “initialized” once. But, if we swap the ordering…

public class Person { private static readonly EmptyPerson empty = new EmptyPerson (); public static readonly Person Empty = empty ; }

Now, empty is an instance of EmptyPerson when Empty is called and everything is good.

Variations

The problem above is only a problem for static fields/properties. If either were to be an expression-member, then ordering doesn’t matter:

public class Person { public static readonly Person Empty => empty ; private static readonly EmptyPerson empty = new EmptyPerson (); } // This variation also works... public class Person { public static readonly Person Empty = empty ; private static readonly EmptyPerson empty => new EmptyPerson (); }

Then, there’s the obvious…

public class Person { public static readonly Person Empty = new EmptyPerson (); }

But, I opted to use the private member in several other spots within my code…

But, don’t do this!

Just as a final warning, don’t do this because while you have a getter -only (i.e. readonly), you’ll also create a new instance of EmptyPerson every time Empty is called. 🤯