randy909
randy909

Reputation: 396

.NET Reflection - How to get "real" type from out ParameterInfo

I'm trying to validate that a parameter is both an out parameter and extends an interface (ICollection). The reflection api doesn't seem to want to give me the "real" type of the parameter, only the one with an "&" at the end which will not evaluate correctly in an IsAssignableFrom statement. I've written some c# code that works but it seems like there should be a better way to do this.

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

Is there a way to get realType without reloading the Type from its string name? I'm still on .NET 2.1.

Thanks, Randy

Upvotes: 20

Views: 13580

Answers (4)

RSTavares
RSTavares

Reputation: 21

See this:

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

Upvotes: 2

Sarath Subramanian
Sarath Subramanian

Reputation: 21291

You could also use

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

if ParameterType.GetElementType() doesn't work

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1500525

An out parameter is "by ref" - so you'll find pInfo.ParameterType.IsByRef returns true. To get the underlying not-by-ref type, call GetElementType():

Type realType = pInfo.ParameterType.GetElementType();

(You should only do that if it is by ref, of course. This applies for ref parameters too.)

Upvotes: 26

driis
driis

Reputation: 164291

Is pInfo.ParameterType not the type you are looking for ?

According to docs, the ParamterType property of the PropertyInfo class is: "The Type object that represents the Type of this parameter."

Also, the following code gives the expected output:

    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: As John Skeet points out, if the parameter is by ref; you should use GetElementType to get the correct type. I updated the code sample.

Upvotes: 6

Related Questions