2011-03-25 21 views
16

En las definiciones de clase y método, es posible agregar restricciones de tipo como where T : IFoo.Reflexión sobre restricciones de tipo

¿Es posible reflexionar sobre esas limitaciones con System.Type o MethodInfo? No he encontrado nada hasta ahora; cualquier ayuda será apreciada

Respuesta

19

Puede recorrer los parámetros genéricos con el tipo, y para cada parámetro, puede solicitar los tipos de restricciones.

Esto se hace usando:

Echa un vistazo a este código, que se puede ejecutar a través de LINQPad:

void Main() 
{ 
    Type type = typeof(TestClass<>); 
    foreach (var parm in type.GetGenericArguments()) 
    { 
     Debug.WriteLine(parm.Name); 
     parm.GetGenericParameterConstraints().Dump(); 
    } 
} 

public class TestClass<T> 
    where T : Stream 
{ 
} 

La salida es:

 
T 

Type [] (1 item) 
typeof (Stream)

encontrar otras limitaciones, tales como new(), puede utilizar el enum de indicadores .GenericParameterAttributes, ejemplo:

void Main() 
{ 
    Type type = typeof(TestClass<>); 
    foreach (var parm in type.GetGenericArguments()) 
    { 
     Debug.WriteLine(parm.Name); 
     parm.GetGenericParameterConstraints().Dump(); 
     parm.GenericParameterAttributes.Dump(); 
    } 
} 

public class TestClass<T> 
    where T : new() 
{ 
} 

que da salida:

 
T 

Type [] (1 item) 
typeof (Stream) 

DefaultConstructorConstraint
+0

muchas gracias! ¡estupendo! –

2

El uso de un determinado anteriormente System.Type puede utilizar GetGenericParameterConstraints().

Aquí hay un excelente artículo de MSDN en Generics and Reflection.

+0

muchas gracias! –

0

Lasse answer señala los métodos pertinentes Type. Lo utilicé como referencia, mientras que la creación de este método de extensión:

public static IList<Tuple<Type, Type[], GenericParameterAttributes>> GetTypeConstraints(this Type type) 
{ 
    return type.GetGenericArguments() 
     .Select(t => Tuple.Create(t, t.GetGenericParameterConstraints(), t.GenericParameterAttributes)) 
     .Where(t => t.Item2.Length > 0 || t.Item3 > GenericParameterAttributes.None) 
     .ToList(); 
} 

Curiosamente, parece que la propiedad Type.BaseType en un parámetro genérico también devuelve una única restricción de tipo.

Cuestiones relacionadas