|
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.
|