2009-04-10 15 views
18

Estoy intentando validar que un parámetro es tanto un parámetro de salida como una interfaz (ICollection). La API de reflexión no parece querer darme el tipo de parámetro "real", solo el que tiene un "&" al final que no se evaluará correctamente en una instrucción IsAssignableFrom. He escrito un código C# que funciona pero parece que debería haber una mejor manera de hacerlo..NET Reflection - Cómo obtener el tipo "real" de fuera ParameterInfo

bool isCachedArg(ParameterInfo pInfo) 
{  
    if (!pInfo.IsOut) 
     return false; 

    string typeName = pInfo.ParameterType.FullName; 
    string nameNoAmpersand = typeName.Substring(0, typeName.Length - 1); 
    Type realType = Type.GetType(nameNoAmpersand); 

    if (!typeof(ICollection).IsAssignableFrom(realType)) 
     return false; 

    return true; 
} 

¿Hay alguna manera de obtener realType sin volver a cargar el Tipo desde su nombre de cadena? Todavía estoy en .NET 2.1.

Gracias, Randy

Respuesta

23

Un parámetro out es "por ref", por lo que encontrará pInfo.ParameterType.IsByRef devuelve verdadero. Para obtener la no-por-ref tipo subyacente, llame GetElementType():

Type realType = pInfo.ParameterType.GetElementType(); 

(Sólo debe hacerlo si es por ref, por supuesto, esto se aplica para ref parámetros también..)

+0

+1 "Un parámetro de salida es 'por ref'". –

+0

Tiene toda la razón, me perdí la parte de ref en mi respuesta :-) +1. – driis

+0

Funciona muy bien. ¡Gracias! – randy909

5

Es pInfo.ParameterType no el tipo que busca?

De acuerdo con documentos, la propiedad ParamterType de la clase PropertyInfo es: "The Type object that represents the Type of this parameter."

Además, el siguiente código da el resultado esperado:

Type t = typeof (X); 
    var mi = t.GetMethod("Method"); 
    var parameters = mi.GetParameters(); 
    foreach(Type parameterType in parameters.Select(pi => pi.ParameterType)) 
      Console.WriteLine(parameterType.IsByRef ? parameterType.GetElementType() : parameterType); 

Editar: Como John Skeet señala, si el parámetro es por ref; debe usar GetElementType para obtener el tipo correcto. Actualicé la muestra del código.

0

también es posible usar

Type type = Type.GetType("System."+ pInfo.ParameterType.Name); 

si ParameterType.GetElementType() no funciona

0

ver esto:

var parameters = methodinfo.GetParameters(); 
foreach (var parameter in parameters) 
{ 
    var HasValue = ""; 
    Type ParameterType = (parameter.IsOut || parameter.ParameterType.IsByRef) ? parameter.ParameterType.GetElementType() : parameter.ParameterType; 
    if (ParameterType.GetProperties().Count() == 2 && ParameterType.GetProperties()[0].Name.Equals("HasValue")) 
    { 
     HasValue = "?"; 
     ParameterType = ParameterType.GetProperties()[1].PropertyType; 
    } 
    StringBuilder sb = new StringBuilder(); 
    using (StringWriter sw = new StringWriter(sb)) 
    { 
     var expr = new CodeTypeReferenceExpression(ParameterType); 
     var prov = new CSharpCodeProvider(); 
     prov.GenerateCodeFromExpression(expr, sw, new CodeGeneratorOptions()); 
    } 
    var result = string.Concat(sb.ToString(), HasValue, " ", parameter.Name); 
    Console.WriteLine(result); 
} 
Cuestiones relacionadas