Reputation: 396
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
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
Reputation: 21291
You could also use
Type type = Type.GetType("System."+ pInfo.ParameterType.Name);
if ParameterType.GetElementType()
doesn't work
Upvotes: 0
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
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