Share via


Sharing static fields among generic class instances

Someone posted on an internal DL on how he can share static fields for all instances of the generic class (among all instances of different closed constructed types). The answer is you can't and I quote the C# 2.0 spec on this (so you better believe me)

§20.1.5: A static variable in a generic class declaration is shared amongst all instances of the same closed constructed type (§20.5.2), but is NOT shared amongst instances of different closed constructed types. These rules apply regardless of whether the type of the static variable involves any type parameters or not.

The only way I can think about doing this is to have the generic type derive from a non-generic base class and define the static field in that. The code looks as follows

 class B
{
     public static int bCount = 0;
}

class D<T> : B
{
    public static int dCount = 0;

    public D()
    {
        dCount++;
        bCount++;
    }
}

D<int> d1 = new D<int>();
D<string> d2 = new D<string>();

Console.WriteLine("D::bCount = {0}, D::dCount = {1}", 
                   D<string>.bCount, D<string>.dCount);

 

This prints out D::bCount = 2, D::dCount = 1 indicating bCount is indeed shared between D<int> and D<string> and hence got incremented twice.

I never faced any need to do any such thing and I cannot think of any example where I would need this :(

Comments

  • Anonymous
    February 23, 2007
    It sounds resonable to me because the static field (or method) could use the type T in the declaration:ex.: public static T dCount;PS It appened to me while trying to access some static helper methods in "quick and dirty" mode;)
  • Anonymous
    September 11, 2011
    Such usege of static and generic appears when we want to create some Id generator in base class: class AbstractBase<Type> { static int _nextId = 0; protected int GetNextID() { return ++_nextId; } } class Child1 : AbstractBase<SomeClass> { int ID; public Child() { ID = GetNextID(); } } class Child2 : AbstractBase<SomeClass> { int ID; public Child() { ID = GetNextID(); } }

So in that case we will get different _nextId for each child class, that what we actually want