Static constructors

kick it on DotNetKicks.com

Recently on Stackoverflow.com there was an interesting question asking what “hidden” or not-well-known C# features people would like to share. The first thing that came to my mind was static constructors (just “ctors” henceforth). For example, this is legal C#:

public class Foo 
{
	static Foo()
	{ }

	public Foo()
	{ }
}

public static class Bar
{
	static Bar()
	{ }
}

Well gee, that’s neat, but what good is it? Here’s what MSDN has to say about that:

A static constructor is used to initialize any static data, or to perform a particular action that needs performed once only. It is called automatically before the first instance is created or any static members are referenced.

Essentially, static ctors are commonly best used to set static members of the class (whether the class itself is static or not). With a static class, the only operations that execute when the class is created is the assignment of static field values, and the static ctor.

Here’s an example of how I use this C# feature to set the connection string for a DataContext wrapper named FeedBurner, which is the name of a database server:

public static class FeedBurner
{  
    private static string connectionString;  
  
    static FeedBurner()  
    {  
        SettingManager.OnChange = () =>  
        {  
            FeedBurner.connectionString =  
                    SettingManager.Setting
						("ConnectionString");  
        };  
    }  
  
    public static FeedBurnerDataContext DataContext
    {  
        get
        {
            return new FeedBurnerDataContext
			    (FeedBurner.connectionString);
        }
    }  

SettingManager is a class that watches files with configuration settings and fires off OnChange() whenever these files change. In this example, if the connection string to the FeedBurner database is changed, the entire class will automatically update the connection string it uses to talk with the FeedBurner database, without having to restart the application.

Beware, though. If an Exception occurs in the static ctor, a TypeInitializationException is thrown. From MSDN:

When a class initializer fails to initialize a type, a TypeInitializationException is created and passed a reference to the exception thrown by the type’s class initializer. The InnerException property of TypeInitializationException holds the underlying exception.

And when this occurs, the Visual Studio debugger does not drill down into the static ctor for you to debug it. Instead, if one gets a TypeInitialzationExceptiom, he or she should programmatically force the debugger to break, to examine the local variables and other run-time data.

public class Foo
{
    static Foo()
    {
#if DEBUG
        try
        {
#endif
            // Do something
#if DEBUG
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debugger.Break();
        }
#endif
    }
}

Pretty ugly, huh?

Generally, static ctors should be avoided. They’re usually more trouble than their worth, and there’s usually a better way to accomplish a task than using a static ctor. But they’re a nifty feature! Here are the notes MSDN offers on them:

A static constructor does not take access modifiers or have parameters.

A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced.

A static constructor cannot be called directly.

The user has no control on when the static constructor is executed in the program.

A typical use of static constructors is when the class is using a log file and the constructor is used to write entries to this file.

Static constructors are also useful when creating wrapper classes for unmanaged code, when the constructor can call the LoadLibrary method.

If a static constructor throws an exception, the runtime will not invoke it a second time, and the type will remain uninitialized for the lifetime of the application domain in which your program is running.

Happy coding!

kick it on DotNetKicks.com

About these ads

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: