C# .NET 反射 - 如何从 ParameterInfo 中获取“真实”类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/738277/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 23:16:14  来源:igfitidea点击:

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

c#.netreflection

提问by randy909

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.

我正在尝试验证一个参数既是输出参数又是扩展接口 (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;
}

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

有没有办法在不从其字符串名称中重新加载 Type 的情况下获取 realType?我仍在使用 .NET 2.1。

Thanks, Randy

谢谢,兰迪

采纳答案by Jon Skeet

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

一个out参数是“by ref”——所以你会发现pInfo.ParameterType.IsByRef返回true。要获取底层的非引用类型,请调用GetElementType()

Type realType = pInfo.ParameterType.GetElementType();

(You should only do that if it isby ref, of course. This applies for refparameters too.)

(您应该只有这样做,如果它由参,当然,这适用于ref参数了。)

回答by driis

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

pInfo.ParameterType 不是您要查找的类型吗?

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

根据文档,PropertyInfo 类的 ParamterType 属性是: 表示此参数类型的 Type 对象。

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.

编辑:正如 John Skeet 指出的那样,如果参数是通过 ref; 您应该使用 GetElementType 来获取正确的类型。我更新了代码示例。

回答by Sarath Avanavu

You could also use

你也可以使用

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

if ParameterType.GetElementType()doesn't work

如果ParameterType.GetElementType()不起作用

回答by RSTavares

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