【问题标题】:.NET Reflection - How to get "real" type from out ParameterInfo.NET 反射 - 如何从 ParameterInfo 中获取“真实”类型
【发布时间】:2009-04-10 17:19:53
【问题描述】:

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

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

谢谢, 兰迪

【问题讨论】:

    标签: c# .net reflection


    【解决方案1】:

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

    Type realType = pInfo.ParameterType.GetElementType();
    

    (当然,只有当它 引用时,你才应该这样做。这也适用于 ref 参数。)

    【讨论】:

    • 如果我发现参数类型是 bool 或 int 或其他类型,我如何创建该类型的实例,给它一个值,然后使用数组或参数调用方法或构造函数?
    • pInfo.ParameterType.GetElementType();为我的布尔参数返回 null。 Type.GetType(pi.ParameterType.FullName) 得到了我想要的,但现在我如何实际制作一个布尔值并给它一个值,以便我可以将它给一个方法或构造函数?
    • @towps 是的,它会为一个简单的布尔参数返回 null - 它没有元素类型。您的问题有点混乱,听起来应该是一个完整的问题,而不仅仅是对另一个问题的答案的评论。
    • 编译器将OutAttribute应用于out参数,并使用它来区分out参数和ref参数。
    【解决方案2】:

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

    根据文档,PropertyInfo 类的 ParamterType 属性是: "The Type object that represents the Type of this parameter."

    此外,以下代码给出了预期的输出:

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

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

    【讨论】:

      【解决方案3】:

      看这个:

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

      【讨论】:

      • 我花了一天时间试图找到/写这样的东西。没有人欣赏它,所以我在这里。谢谢!
      【解决方案4】:

      你也可以使用

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

      如果ParameterType.GetElementType() 不起作用

      【讨论】:

        猜你喜欢
        • 2011-06-28
        • 1970-01-01
        • 2022-11-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-22
        • 2017-04-14
        相关资源
        最近更新 更多