2011-06-07 16 views
6

Tengo un fragmento de código en el que a veces necesito crear un nuevo tipo genérico, pero con un número desconocido de parámetros genéricos. Por ejemplo:Fabricación de genéricos con muchos tipos

public object MakeGenericAction(Type[] types) 
{ 
    return typeof(Action<>).MakeGenericType(paramTypes); 
} 

El problema es que si tengo más de un Tipo en mi matriz, el programa se bloqueará. En el corto plazo, he encontrado algo así como un paso intermedio.

public object MakeGenericAction(Type[] types) 
{ 
    if (types.Length == 1) 
    { 
    return typeof(Action<>).MakeGenericType(paramTypes); 
    } 
    else if (types.Length ==2) 
    { 
    return typeof(Action<,>).MakeGenericType(paramTypes); 
    } 
    ..... And so on.... 
} 

Esto funciona, y es bastante fácil de cubrir mis escenarios, pero parece realmente hacky. ¿Hay una mejor manera de manejar esto?

Respuesta

5

En ese caso, sí:

Type actionType = Expression.GetActionType(types); 

El problema aquí es que aunque es probable que va a utilizar DynamicInvoke que es lento.

Un Action<object[]> entonces el acceso de índice puede superar a un Action<...> invoca con DynamicInvoke

+1

solución Hermosa, elegante (o al menos tanto como los genéricos reflexivos pueden ser) – KeithS

+1

Muy bueno. ¿Qué pasaría si tuviera más de 16 tipos en su matriz? Además del código, la policía le quita todos los dispositivos electrónicos. – IndigoDelta

+0

@IndigoDelta los engranajes se caerán; p –

0
Assembly asm = typeof(Action<>).Assembly; 
Dictionary<int, Type> actions = new Dictionary<int, Type>; 
foreach (Type action in asm.GetTypes()) 
    if (action.Name == "Action" && action.IsGenericType) 
     actions.Add(action.GetGenericArguments().Lenght, action) 

entonces puede utilizar el diccionario actions para encontrar rápidamente el tipo correcto:

public Type MakeGenericAction(Type[] types) 
{ 
    return actions[types.Lenght].MakeGenericType(paramTypes); 
}