2009-04-10 7 views
18

J'essaie de valider qu'un paramètre est à la fois un paramètre de sortie et étend une interface (ICollection). L'api de réflexion ne semble pas vouloir me donner le type "réel" du paramètre, seulement celui avec un "&" à la fin qui n'évaluera pas correctement dans une instruction IsAssignableFrom. J'ai écrit du code C# qui fonctionne, mais il semble qu'il devrait y avoir une meilleure façon de le faire..NET Reflection - Comment obtenir le type "réel" de dehors 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; 
} 

Y at-il un moyen d'obtenir realType sans recharger le type de son nom de chaîne? Je suis toujours sur .NET 2.1.

Merci, Randy

Répondre

23

Un paramètre out est "par ref" - donc vous trouverez pInfo.ParameterType.IsByRef retourne vrai. Pour obtenir le sous-jacent non par ref type appelez GetElementType():

Type realType = pInfo.ParameterType.GetElementType(); 

(vous ne devez faire que si elle est par ref, bien sûr Cela vaut pour ref paramètres aussi..)

+0

+1 "Un paramètre out est 'par ref'". –

+0

Vous avez absolument raison, j'ai raté la partie par ref dans ma réponse :-) +1. – driis

+0

Fonctionne très bien. Je vous remercie! – randy909

5

est pInfo.ParameterType pas le type que vous cherchez?

Selon docs, la propriété ParamterType de la classe PropertyInfo est: "The Type object that represents the Type of this parameter."

En outre, le code suivant donne le résultat attendu:

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); 

Edit: Comme John Skeet souligne, si le paramètre est par ref; vous devez utiliser GetElementType pour obtenir le type correct. J'ai mis à jour l'exemple de code.

0

vous pouvez également utiliser

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

si ParameterType.GetElementType() ne fonctionne pas

0

Voir ceci:

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); 
} 
Questions connexes