C# Back to Basics: Static Constructors

Today, let's turn our attention to a very basic, and highly useful feature of C#: Static Constructors. I don't make common use of this feature myself. But, when it is needed, it fits the job very well indeed.

So, what is a static constructor?

To quote the documentation, "A static constructor is used to initialize any static data, or to perform a particular action that needs to be performed once only."

To start with, let's look at some code that satisfies the first part of that quote, and initialize some static data.

public class Clock
{
   static DateTime TIME_STATIC_CONSTRUCTOR_WAS_CALLED;

   static Clock()
   {
      TIME_STATIC_CONSTRUCTOR_WAS_CALLED = DateTime.UtcNow;
   }
}

In the preceding code, we have a static constructor that is used to initialize a static field of type DateTime with the current UTC time. Very simple. However, there are a few things we can note from this code. Firstly, the static constructor does not take any access modifiers. So, for example, if we were to do this…

public static Clock()
{
   TIME_STATIC_CONSTRUCTOR_WAS_CALLED = DateTime.UtcNow;
}

…you would see an error. Furthermore, a static constructor does not accept any parameters, and it cannot be called directly. It is called automatically to initialize the class before the first instance is created or any static members referenced.

My complete code at this point looks like this…

public class Program
{
   public static void Main(string[] args)
   {
      var clock = new Clock();

      Console.WriteLine(clock.Get().Ticks);
   }
}

public class Clock
{
   static DateTime TIME_STATIC_CONSTRUCTOR_WAS_CALLED;

   static Clock()
   {
      TIME_STATIC_CONSTRUCTOR_WAS_CALLED = DateTime.UtcNow;
   }

   public DateTime Get()
   {
      return TIME_STATIC_CONSTRUCTOR_WAS_CALLED;
   }
}

Running this code, which is part of a standard .NET console application, I have an output that looks like Figure 1.

The console application running
Figure 1: The console application running

Now that we have a simple application you may run, let's look at the second part of the quote above, and examine what we mean by 'to perform an action only once.'

As we now know, a static constructor is automatically called once, and called to initialize a class before the first instance of that class is created. Consider the following piece of code.

public static void Main(string[] args)
{
   var clock1 = new Clock();
   Console.WriteLine(clock1.Get().Ticks);

   Thread.Sleep(1000);
   var clock2 = new Clock();
   Console.WriteLine(clock2.Get().Ticks);

   Thread.Sleep(1000);
   var clock3 = new Clock();
   Console.WriteLine(clock3.Get().Ticks);
}

What would you expect the output to the console to be for the other two instances of Clock? The exact DateTime they were initialized? Or the DateTime of the first instance of the class? For the answer, see Figure 2…

The output from the three instances of Clock
Figure 2: The output from the three instances of Clock

Let's compare the behaviour from above, with that of a standard constructor. Let's change the static constructor of our Clock class to something like the following, and re-run the program.

public Clock()
{
   TIME_STATIC_CONSTRUCTOR_WAS_CALLED = DateTime.UtcNow;
}

And the result…

The output showing different results
Figure 3: The output showing different results

The ticks we are looking at now represent the time at which the constructor was called. Each one differs because we are making that call every time the class is initialized.

Conclusion

There isn't a lot to this little feature of C#, but its application can be very powerful to you at the right time. For example, if you're familiar with EntityFramework, you may need to evaluate a connection string at run-time, rather than connected using a constant string. It's also quite possible that once you've evaluated this string, you don't need to do so again for the lifetime of the application.

This is the kind of situation a static constructor can really help, and one I've recently found myself in with a WPF application. I ended up in a situation where the location of a local SQLite database can change, but it never changes once the application is running.

If you have any questions or comments on this article, please find me on Twitter @GLanata.



About the Author

Gavin Lanata

Gavin has been building front-ends to software applications; desktop, web, and mobile, for several years now. Gavin often attends developer events, expanding his own knowledge in the fast paced world of IT, and lending a helping hand to developers needing a little direction navigating the world of design. Gavin has dedicated his time to the study of the many factors influencing human usage and reaction to software application. Art, design and coding name a few but certainly not the least of his tools to find the truths behind why we like and use the things we do.

Related Articles

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • As all sorts of data becomes available for storage, analysis and retrieval - so called 'Big Data' - there are potentially huge benefits, but equally huge challenges...
  • The agile organization needs knowledge to act on, quickly and effectively. Though many organizations are clamouring for "Big Data", not nearly as many know what to do with it...
  • Cloud-based integration solutions can be confusing. Adding to the confusion are the multiple ways IT departments can deliver such integration...

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date