Question

So here is what I'm thinking...

public class MyClass
{
    public const string MyConstant = "MyConstantValue";

    private static MyClass DefaultInstance;

    static MyClass()
    {
         DefaultInstance = new MyClass();
    }
}

...

NotificationService.RegisterForNotification(MyClass.MyConstant, Callback);

Will this work or do I need to use something like a static readonly property field to trigger the static constructor?

Was it helpful?

Solution

Use of a constant doesn't necessarily result in a member access which would cause the static constructor to be called. The compiler is allowed to (encouraged, even) substitute the value of the constant at compile time.

Your suggested workaround of static readonly should be ok, although readonly suggests a field, not a property. Properties are read-only when they have no setter, the readonly keyword isn't involved.

A simple example:

class HasSConstructor
{
    internal const int Answer = 42;
    static HasSConstructor()
    {
        System.Console.WriteLine("static constructor running");
    }
}

public class Program
{
    public static void Main()
    {
        System.Console.WriteLine("The answer is " + HasSConstructor.Answer.ToString());
    }
}

Output under .NET 4.0:

The answer is 42

The static constructor never runs!

OTHER TIPS

Static constructor is called automatically before the first instance is created or any static members are referenced. See here: MSDN: Static Constructors

By the way, constant fields are inherently static, but as pointed they may (and probably will) be substituted by the value itself.

The static constructor will not be called if you're just accessing public constants. For example, consider this class:

class Testo
{
    public const string MyValue = "Hello, world";
    public static readonly int xyzzy;

    static Testo()
    {
        Console.WriteLine("In static constructor");
        xyzzy = 27;
    }
}

Now, in another class, execute:

Console.WriteLine(Testo.MyValue);
Console.WriteLine(Testo.xyzzy);

Your output will be:

Hello, world
In static constructor
27

Constants are hoisted from the class at compile time. So the value of Testo.MyValue does not reference the Testo class at runtime. The static constructor is not called until you call something that requires initialization.

So, yes, you need to access something like a static readonly if you want to ensure that the constructor is called.

No, you don't need such. Static constructor is called when the class is loaded.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top