tags:

views:

165

answers:

4

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?

A: 

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.

Julien Lebosquain
A: 

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

Giorgi
+9  A: 

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
Mark Byers
How's that a static class?
Jouke van der Maas
@Jouke van der Maas, who talked about a static class ? The question is about the static constructor of a generic class, not a static class...
Thomas Levesque
This was neither, so it still applies :)
Jouke van der Maas
@Jesse He edited it, obviously
Jouke van der Maas
+1  A: 

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

Jouke van der Maas