.NET Reflection - как получить "настоящий" тип вне ParameterInfo
Я пытаюсь проверить, что параметр является как выходным параметром, так и расширяет интерфейс (ICollection). Отражение api, похоже, не хочет давать мне "реальный" тип параметра, только тот, у которого есть "&". в конце, который не будет правильно оцениваться в заявлении IsAssignableFrom. Я написал код С#, который работает, но кажется, что должен быть лучший способ сделать это.
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;
}
Есть ли способ получить realType без перезагрузки Type из его имени строки? Я все еще на .NET 2.1.
Спасибо,
Ренди
Ответы
Ответ 1
Параметр out
является "по ref", поэтому вы обнаружите, что pInfo.ParameterType.IsByRef
возвращает true. Чтобы получить базовый тип not-by-ref, вызовите GetElementType()
:
Type realType = pInfo.ParameterType.GetElementType();
(Вы должны сделать это, только если это верно, это относится к параметрам ref
).
Ответ 2
Является ли pInfo.ParameterType не тем типом, который вы ищете?
Согласно документам, свойство ParamterType класса PropertyInfo:
Объект Type, который представляет тип этого параметра.
Кроме того, следующий код дает ожидаемый результат:
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);
Изменить: Как указывает Джон Скит, если параметр равен ref; вы должны использовать GetElementType для получения правильного типа. Я обновил образец кода.
Ответ 3
Вы также можете использовать
Type type = Type.GetType("System."+ pInfo.ParameterType.Name);
если ParameterType.GetElementType()
не работает
Ответ 4
Смотрите это:
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);
}