Отражение .NET - Как получить «реальный» тип из ParameterInfo - PullRequest
19 голосов
/ 10 апреля 2009

Я пытаюсь проверить, что параметр является как выходным параметром, так и расширяет интерфейс (ICollection). Кажется, API-интерфейс отражения не хочет давать мне «реальный» тип параметра, а только тот, который имеет «&» в конце, что не будет правильно оцениваться в операторе IsAssignableFrom. Я написал некоторый код на C #, который работает, но, похоже, должен быть лучший способ сделать это.

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.

Спасибо, Randy

Ответы [ 4 ]

24 голосов
/ 10 апреля 2009

Параметр out имеет значение "по ссылке" - поэтому вы найдете, что pInfo.ParameterType.IsByRef возвращает значение true. Чтобы получить базовый тип non-by-ref, позвоните GetElementType():

Type realType = pInfo.ParameterType.GetElementType();

(Вы должны делать это, только если равно по ссылке, конечно. Это относится и к ref параметрам.)

5 голосов
/ 10 апреля 2009

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, чтобы получить правильный тип. Я обновил пример кода.

0 голосов
/ 29 марта 2017

Смотрите это:

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);
}
0 голосов
/ 01 декабря 2014

Вы также можете использовать

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

если ParameterType.GetElementType() не работает

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...