Static Generic Class as Dictionary

A static field in a generic class will have a separate value for each combination of generic parameters. It can therefore be used as a Dictionary<Type, whatever>

Is this better or worse than a static Dictionary<Type, whatever>?

In other words, which of these implementations is more efficient?

public static class MethodGen<TParam> {
    public static readonly Action<TParam> Method = CreateMethod();
    static Action<TParam> CreateMethod() { /*...*/ }
}

Or,

public static class MethodGen {
    static readonly Dictionary<Type, Delegate> methods 
              = new Dictionary<Type, Delegate>();

    public static Action<T> GetMethod<T>() {
        //In production code, this would ReaderWriterLock

        Delegate method;
        if(!methods.TryGetValue(typeof(T), out method)
            methods.Add(typeof(t), method = CreateMethod<T>());
        return method;
    }

    static Action<T> CreateMethod<T>() { /*...*/ }
}

In particular, how does the CLR lookup the static fields by generic type parameter?


Solution 1:

I like using generic types this way. In particular, I often have private nested generic classes for precisely this purpose.

The main thing I like about it is that it's hard not to get the initialization right this way (in terms of thread safety), given the way type initialization works. The only problem is what to do if initialization fails - occasionally I've resorted to remembering an exception to throw on first necessary access, but that's pretty rare.

I wouldn't like to guess at exactly how the CLR looks up the type via the type arguments, but I'm pretty sure it'll be optimised to heck and back :)

Solution 2:

I believe that the generic (first) version would do the dictionary lookup at compile time, and therefore perform better at runtime.

However, it might use more memory.

Solution 3:

I haven't profiled it (which is the only way to really answer this question - the difference in performance may be so small as to be meaningless) but I would hazard a guess that the locking is the expensive part. The CLR does do the locking for you - and does so in a way defined by experts in this field! - so I expect if there is a difference, it would be in favour of using the language feature rather than building it yourself with Dictionary + locking.

Solution 4:

It doesn't store values for each generic type parameter as much as it really creates (conceptually anyways) N distinct classes - one for each type T that you use it with.