Jim Rogers

Lives in Baton Rouge, LA, with two dogs, one cat, and one lovely wife. I'm a lead developer for GCR & Associates.

Katrin and Jim

Month List

Static Members on Generics

by Jim Oct 24, 2008 9:01 PM

I’m currently porting a library from Java to C# that relies heavily on generics. In the process I’m finding out all sorts of interesting things about generics in C#, including this tidbit:

A static member of a generic class has one instance per closed generic type, NOT one instance for the overall type definition.

So for instance if you have:

public class BadGeneric<T>
{ 
    public static Dictionary<int, string> stuff = new Dictionary<int, string>();
}

and you instantiate instances of this with different type parameters:

BadGeneric<int> test1 = new BadGeneric<int>();
BadGeneric<int> test2 = new BadGeneric<int>();
BadGeneric<string> test3 = new BadGeneric<string>();

you might think you would have one instance of the dictionary - and you would be wrong. The first two share a dictionary, but BadGeneric<string> is a different type, and gets its own separate instance of the dictionary!

Don’t be confused by the fact that Dictionary is itself generic; this happens with all static members, regardless of type. Dictionary is a likely example because it’s the sort of thing you might want to add to in constructors and access across all instances of BadGeneric<>.

Now what?

One solution, explained with much preamble here on CodeProject, is to wrap the static member in a non-generic class, defined separately:

public class GoodGeneric<T>
{
    public static Dictionary<int, string> stuff
    {
        get { return GenericStaticState._stuff; } 
    }
}

internal class GenericStaticState {
    public static Dictionary<int, string> _stuff = new Dictionary<int, string>();
}

Another possibility is to derive the generic class from a non-generic base:

public abstract class NonGenericBase {
    public static Dictionary<int, string> _stuff = new Dictionary<int, string>();
}

public class Generic<T> : NonGenericBase { 
    public static Dictionary<int, string> stuff
    {
        get { return _stuff; }
    }
}

I think the first is probably a little cleaner, unless you’re using a non-generic base anyway, or an interface that could be converted to one. But don’t see any particular weaknesses with either method.

Tags:

Code

Add comment

  Country flag

biuquote
  • Comment
  • Preview
Loading