Question

Given the following classes:

public class Foo {
    static Foo() {
        Console.WriteLine("Foo is being constructed");
    }
}

public class Bar {
    public void ReferenceFooAsGenericTypeParameter<T>() {
        Console.WriteLine("Foo is being referenced as a generic type parameter");
    }
}

public class SampleClass
{
    public static void Main()
    {
        new Bar().ReferenceFooAsGenericTypeParameter<Foo>();
    }
}

The output is

Foo is being referenced as a generic type parameter

This makes sense, according to the spec:

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

But I'm curious why the static constructor is not invoked when the type is referenced as a generic type parameter.

Was it helpful?

Solution

Why would it need to be?

The point of the static constructor being called normally is to make sure that any state set up within the static constructor is initialized before it's first used.

Just using Foo as a type argument doesn't make use of any state within it, so there's no need for the static constructor to be called.

You might want to try creating a static variable initializer with side effects (e.g. a method call which then prints to the console) and removing the static constructor - that can affect the timing of initialization significantly in some cases. It may trigger it here.

OTHER TIPS

That's because you can't actually use the type contents in any meaningful way just by inclusion as a generic type parameter, the type needs to have something done to it to warrant a static constructor being called.

And you're correct that this is in line with the specification. Section 10.12 (Static Constructors) states:

The execution of a static constructor is triggered by the first of the following events to occur within an application domain:

· An instance of the class type is created.

· Any of the static members of the class type are referenced.

Use as a generic type parameter is neither of these.

The thing to note here is that in new Bar().ReferenceFooAsGenericTypeParameter<Foo>(); you have created an object of type Bar, neither your main nor Bar have create an instance of Foo nor has any of it's members been accessed, in the case presented, the type itself merely being passed as a param.

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