C# Snippet Tutorial - Static Constructors [Beginner]


I'm going to guess that pretty much everyone who reads this blog knows about constructors and how they work. And I bet everyone knows about static variables and functions as well. But did you know that there is such a thing as a static constructor in C#? Yup, a static constructor. And that's what we are going to take a look at today.

The concept behind them is actually pretty simple. A static constructor in C# is a chunk of code that is executed right after all the static variables for a class are initialized. You declare it similar to the way you declare a regular constructor (except that it is declared static). So in many ways, they act exactly like a class constructor, except for statics. Don't worry, if that didn't make perfect sense, there are plenty of examples to come.

Lets take a look at a really simple class with a static constructor:
public class StaticTest
{
  public static int SomeVarA;

  static StaticTest()
  {
    SomeVarA = 1; 
  }
}
 
Granted, that is a pretty silly constructor, since I could have initialized SomeVarA right up in the field declaration. But it gets the point across. The static constructor has to follow all the rules of a normal static function, i.e., no this keyword and things like that. In addition, it doesn't have a private/public/protected modifier. This is because those modifiers don't make sense in this context - no one can ever directly call this function. Also, it can't take any arguments - again, because no one ever actually directly calls this function.

If no one ever directly calls this function, when does it actually get run? Well, that is a good question. Essentially, the first time someone touches the class, by creating an instance, or by touching some static variable or function, the static constructor gets run. We can actually see this in action:
public class Program
{
  static void Main(string[] args)
  {
    Debug.WriteLine("Start Time: " + Environment.TickCount);
    Debug.WriteLine("StaticTest Static Field At: " + StaticTest.AFieldToAccess);
  }
}

public class StaticTest
{
  public static long AFieldToAccess = Environment.TickCount;

  static StaticTest()
  {
    Debug.WriteLine("StaticTest Static Constructor At: " + Environment.TickCount);
  }
}
 
Running this code produces the following output (or something similar, depending on your current computer time):
Start Time: 167393939
StaticTest Static Constructor At: 167393959
StaticTest Static Field At: 167393959
 
So we hit the start time first, as expected, and then because we are hitting on the StaticTest class for the first time (we are trying to access AFieldToAccess), the static constructor runs.

Creating an instance of StaticTest would have the same affect:
public class Program
{
  static void Main(string[] args)
  {
    Debug.WriteLine("Start Time: " + Environment.TickCount);
    new StaticTest();
    new StaticTest();
    new StaticTest();
  }
}

public class StaticTest
{
  public static long AFieldToAccess = Environment.TickCount;

  static StaticTest()
  {
    Debug.WriteLine("StaticTest Static Constructor At: " + Environment.TickCount);
  }

  public StaticTest()
  {
    Debug.WriteLine("StaticTest Regular Constructor At: " + Environment.TickCount);
  }
}
 
This produces the output:
Start Time: 167855613
StaticTest Static Constructor At: 167855633
StaticTest Regular Constructor At: 167855633
StaticTest Regular Constructor At: 167855633
StaticTest Regular Constructor At: 167855633
 
As expected, the static constructor runs only once, right before any of the StaticTest objects get instantiated.

So What happens if StaticTest is never referred to? Well, the static constructor never gets run:
public class Program
{
  static void Main(string[] args)
  {
    Debug.WriteLine("Start Time: " + Environment.TickCount);
  }
}

public class StaticTest
{
  public static long AFieldToAccess = Environment.TickCount;

  static StaticTest()
  {
    Debug.WriteLine("StaticTest Static Constructor At: " + Environment.TickCount);
  }
}
 
In this case, the only output is:
Start Time: 168189944
 
This shows that static constructors don't 'just run' - they are only triggered when code touches a class for the first time.

What are static constructors useful for? They have come in handy every once in a while when I have needed to initialize some static fields in a complex way. For example, say you have a static class that the rest of your code uses to do database access. A static constructor is a handy place to initialize that database connection, because it means that the connection will get created right before it is first needed. There are plenty of other uses for them as well - that just happens to be the fist one that popped into my head.

That is it for this short primer on static constructors C#. Thanks for reading.

Comments