2009-03-26 22 views
16

Un campo estático en una clase genérica tendrá un valor separado para cada combinación de parámetros genéricos. Por lo tanto, se puede utilizar como un diccionario < tipo, sea cual sea >Clase genérica estática como diccionario

¿Es esta mejor o peor que un diccionario estático < tipo, sea cual sea >?

En otras palabras, ¿cuál de estas implementaciones es más eficiente?

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

O

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>() { /*...*/ } 
} 

En particular, ¿cómo funciona el CLR lookup los campos estáticos de parámetro de tipo genérico?

+0

cómo implementar su acción estática CreateMethod ()? –

+0

¡Y justo cuando estaba pensando en eso! +1 – nawfal

Respuesta

12

Me gusta usar tipos genéricos de esta manera. En particular, a menudo tengo clases genéricas privadas anidadas precisamente para este propósito.

Lo principal que me gusta es que es difícil no para obtener la inicialización de esta manera (en términos de seguridad de subprocesos), dada la forma en que funciona la inicialización de tipos. El único problema es qué hacer si falla la inicialización; ocasionalmente he recurrido a recordar una excepción para lanzar el primer acceso necesario, pero eso es bastante raro.

no me gustaría que adivinar exactamente cómo el CLR busca el tipo a través de los argumentos de tipo, pero estoy bastante seguro de que va a ser optimizado para diablos y de vuelta :)

1

No almacena valores para cada parámetro de tipo genérico tanto como realmente crea (conceptualmente de todos modos) N clases distintas, una para cada tipo T con el que la utilice.

+0

Hmmm ... ¿Estás seguro de que es así? Pensé que solo formaba una clase para todos los tipos de referencia, y luego una para cada tipo de valor con la que podría usarla. –

+2

Utiliza una copia del código nativo para todos los tipos de referencia, pero hay distintos objetos Type. –

1

creo que la versión genérica (primera) haría la búsqueda del diccionario en tiempo de compilación y, por lo tanto, funcionaría mejor en tiempo de ejecución.

Sin embargo, podría necesitar más memoria.

2

No lo he perfilado (que es la única forma de responder realmente a esta pregunta, la diferencia de rendimiento puede ser tan pequeña que no tiene sentido) pero me atrevo a adivinar que el bloqueo es la parte cara. ¡El CLR hace el bloqueo por usted, y lo hace de una manera definida por expertos en este campo! - así que espero que si hay una diferencia, sería a favor de usar la función de idioma en lugar de compilarla tú mismo con Dictionary + bloqueo.