2009-04-10 6 views
18

Ich versuche zu validieren, dass ein Parameter sowohl ein out-Parameter ist und erweitert eine Schnittstelle (ICollection). Die Reflexion api scheint mir nicht den "echten" Typ des Parameters geben zu wollen, sondern nur den mit einem "&" am Ende, der in einer IsAssignableFrom-Anweisung nicht korrekt ausgewertet wird. Ich habe einen C# -Code geschrieben, der funktioniert, aber es scheint, als sollte es einen besseren Weg geben, dies zu tun..NET Reflection - Wie bekomme ich "echten" Typ aus 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; 
} 

Gibt es eine Möglichkeit, RealType zu erhalten, ohne den Type von seinem String-Namen neu zu laden? Ich bin immer noch auf .NET 2.1.

Danke, Randy

Antwort

23

Ein out Parameter ist "by ref" - so finden Sie pInfo.ParameterType.IsByRef gibt True zurück. die zugrunde liegenden nicht-by-ref-Typ zu erhalten, rufen Sie GetElementType():

Type realType = pInfo.ParameterType.GetElementType(); 

(Sie sollten nur tun, wenn es durch ref ist natürlich Auch dies für ref Parameter gilt..)

+0

+1 "Ein out-Parameter ist 'by ref'". –

+0

Du hast absolut recht, ich habe den by ref Teil in meiner Antwort verpasst :-) +1. – driis

+0

Funktioniert gut. Vielen Dank! – randy909

5

Ist pInfo.ParameterType nicht der Typ, die Sie suchen?

docs Nach der ParamterType Eigenschaft der Propertyinfo-Klasse ist: "The Type object that represents the Type of this parameter."

Auch der folgende Code gibt die erwartete Ausgabe:

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: Als John Skeet darauf hinweist, wenn der Parameter durch ref ist; Sie sollten GetElementType verwenden, um den richtigen Typ zu erhalten. Ich habe das Codebeispiel aktualisiert.

0

Sie könnten auch

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

wenn ParameterType.GetElementType() funktioniert nicht

diese
0

nachschauen:

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); 
} 
Verwandte Themen