如何在C#方法中识别每个参数类型?

8

我有一个 C# 方法,如下:

MyMethod(int num, string name, Color color, MyComplexType complex)

使用反射,我如何明确识别任何方法的每个参数类型?
我想按参数类型执行某些任务。如果类型是简单的int、string或boolean,则执行一些操作;如果是Color、XMLDocument等,则执行其他操作;如果是用户自定义类型,如MyComplexType或MyCalci等,则我想执行某些任务。
我可以使用ParameterInfo检索方法的所有参数,并可以循环遍历每个参数并获取其类型。但是我如何识别每种数据类型呢?
foreach (var parameter in parameters)
{
    //identify primitive types??
    //identify value types
    //identify reference types

}

编辑:这是我创建属性网格页面的代码部分,我想展示所选方法的参数列表及其数据类型。如果参数具有任何用户定义类型/引用类型,则希望进一步展开以显示其下所有元素及其数据类型。


你想对复杂类型参数做什么? - Victor Haydin
你面临的问题比那个大得多,你如何生成适当的值来进行调用?仔细思考,答案就会浮现出来。看看动态关键字。 - Hans Passant
@mace,基本上,我正在尝试创建一个类似属性页的东西,在该页面上应显示参数及其类型。如果它是一个类似MyComplexType的引用类型,那么我会展开该类型以找到其中的其他类型。如果它不是int、string或color等基本类型,则无需在其中进行检查。希望你明白我的意思。 - Sri Reddy
2个回答

15

使用ParameterInfo.ParameterType

 using System;
 using System.Reflection;

 class parminfo
 {
    public static void mymethod (
       int int1m, out string str2m, ref string str3m)
    {
       str2m = "in mymethod";
    }

    public static int Main(string[] args)
    {
       Console.WriteLine("\nReflection.Parameterinfo");

       //Get the ParameterInfo parameter of a function.

       //Get the type.
       Type Mytype = Type.GetType("parminfo");

       //Get and display the method.
       MethodBase Mymethodbase = Mytype.GetMethod("mymethod");
       Console.Write("\nMymethodbase = " + Mymethodbase);

       //Get the ParameterInfo array.
       ParameterInfo[]Myarray = Mymethodbase.GetParameters();

       //Get and display the ParameterInfo of each parameter.
       foreach (ParameterInfo Myparam in Myarray)
       {
          Console.Write ("\nFor parameter # " + Myparam.Position 
             + ", the ParameterType is - " + Myparam.ParameterType);
       }
       return 0;
    }
 }
如果您需要在检索后检查System.Type,您可以像David所提到的那样使用IsPrimitiveIsByRef。此外,您还可以使用IsValueType。在System.Type类中有大量的Is *属性。您最好查看每个Is *属性的MSDN文档,例如:IsClass表示...

  

获取一个值,该值指示类型是否为类;即不是值类型或接口。

因此,您可以推断出IsValueType不需要被调用。请记住,给定类型可以在多个属性上返回true,例如IsClass可以返回true,并且IsPassByRef也可以返回true。也许为已知的CLR类型提供逻辑,因为这些类型不会改变,而且您事先知道它们,然后构建用户定义的复杂类型的逻辑。您可以采取内置逻辑的方法来处理CLR类型;两种方法都可以。

我能够获取参数的类型。现在我该如何确定每种类型,无论它是引用类型、值类型还是基本类型?我希望有一个通用的代码可以对传递给它的任何方法执行此操作。 - Sri Reddy
ParameterType 返回一个 System.Type,它有一个名为 IsByRef 的属性(告诉你它是否是引用类型),还有另一个名为 IsPrimitive 的属性。 - Amanda Mitchell
@user465876除了David提到的额外评论外,还添加了对IsValueType的引用。 - Aaron McIver
@Dave,Aaron,感谢回复。我想这个方法行不通。我比较了Int32、String、Color、MyComplexType/MyClass的属性,结果并不是很有帮助。Int32和Color的IsValueType=true,IsPrimitive=true,IsClass=false,IsByRef=false。对于String、MycomplexType/MyClass,它们的IsValueType=false,IsPrimitive=false,IsClass=true,IsByRef=false。我担心即使我满足上述所有条件,如何确保它适用于用户在方法中定义的每种类型?我不能检查每一种类型。属性属性能以任何方式帮助吗? - Sri Reddy
@user465876 在帖子中添加了额外的注释...它归结为利用Is*属性来定义每种类型应该采取的后勤路径。 - Aaron McIver

2

要获取参数的实际Type,请使用ParameterInfo值上的ParameterType。有了这个值,您可以使用多种方式来识别类型。最简单的方法是与已知类型进行直接比较。

if (parameter.ParameterType == typeof(int)) { 
  ...
}

或者在类型不可用的情况下,可以使用名称匹配(尽管这有点不可靠,因为重构操作可能会忽略字符串常量并默默地破坏应用程序)

if (parameter.ParameterType.Name == "TheTypeName") {
  ...
}

这种方式将限制我使代码通用于任何方法..或者我必须检查C#中存在的每种类型。我希望有一种通用的方法来动态检查参数类型。 - Sri Reddy
如果您只关心原始类型,那么只需使用IsPrimitive属性即可。@user465876 - JaredPar
我认为我可以恰当地解释。实际上,我想编写通用代码,该代码将读取方法名称并获取所有参数,然后将它们与其类型一起写入页面。如果类型是引用类型(用户定义的),则应进一步展开以检查其中的类型并将其写入页面。类似于属性网格。我关心每种类型,以便我知道哪个需要更多扩展。 - Sri Reddy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接