C# Generic Static Constructor

C#Generics

C# Problem Overview


Will a static constructor on a generic class be run for every type you pass into the generic parameter such as this:

 class SomeGenericClass<T>
 {
      static List<T> _someList;
      static SomeGenericClass()
      {
          _someList = new List<T>();
      }
 }

Are there any draw backs to using this approach?

C# Solutions


Solution 1 - C#

Yes, the static constructor will be called once for each closed class type (the type created when you specify the type parameters). See the C# 3 specification, §10.12 Static constructors.

> The static constructor for a closed class type executes at most once in a given application domain.

and also:

> Because the static constructor is executed exactly once for each closed constructed class type, it is a convenient place to enforce run-time checks on the type parameter that cannot be checked at compile-time via constraints (§10.1.5). For example, the following type uses a static constructor to enforce that the type argument is an enum:

class Gen<T> where T: struct
{
	static Gen() {
		if (!typeof(T).IsEnum) {
			throw new ArgumentException("T must be an enum");
		}
	}
}

It is also relevant to read §4.4.2 Open and closed types:

> At run-time, all of the code within a generic type declaration is executed in the context of a closed constructed type that was created by applying type arguments to the generic declaration. Each type parameter within the generic type is bound to a particular run-time type. The run-time processing of all statements and expressions always occurs with closed types, and open types occur only during compile-time processing. > > Each closed constructed type has its own set of static variables, which are not shared with any other closed constructed types.

This program that you can run yourself demonstrates that the static constructor is called three times, not just once:

public class Program
{
    class SomeGenericClass<T>
    {
        static SomeGenericClass()
        {
            Console.WriteLine(typeof(T));
        }
    }

    class Baz { }

    static void Main(string[] args)
    {
        SomeGenericClass<int> foo = new SomeGenericClass<int>();
        SomeGenericClass<string> bar = new SomeGenericClass<string>();
        SomeGenericClass<Baz> baz = new SomeGenericClass<Baz>();
    }
}

Output:

System.Int32
System.String
Program+Baz

Solution 2 - C#

It will work, but a new 'instance' will be created for every type you use.

Solution 3 - C#

Yes, static members and constructors for generic types are specific to a generic parameter and will be run for every different type. There are no real drawbacks. Just be careful when refactoring a non-generic class into a generic one.

Solution 4 - C#

Yes, it will run for every type you supply because for every different supplied type you get separate type.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSeattle LeonardView Question on Stackoverflow
Solution 1 - C#Mark ByersView Answer on Stackoverflow
Solution 2 - C#Jouke van der MaasView Answer on Stackoverflow
Solution 3 - C#Julien LebosquainView Answer on Stackoverflow
Solution 4 - C#GiorgiView Answer on Stackoverflow