C#反射编程——Type类
在C#的反射机制中Type类常用于获取类的类型。如表示类型声明类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义以及开放或封闭构造的泛型类型。我们可以通过下列代码获取一个Type类型的对象用来代表String类型。// 方法1使用typeof运算符 Type t typeof(String); // typeof(x)中的x必须是具体的类名、类型名称等不可以是变量名称。 // 方法2使用GetType()方法 String s Hello world!; Type t s.GetType(); // GetType()方法继承自Object所以C#中任何对象都具有GetType()方法 //方法3使用Type类的静态方法GetType() Type t Type.GetType(System.Double);在获取Type类型的实例 t 后可以通过 t 来获取Stirng类型的各种内部元素例如构造器、字段、方法等等。下面的示例显示了Type的几个代表性特性。一、Type类中的常用属性属性描述Name数据类型名FullName数据类型的完全限定名(包括命名空间名)Namespace定义数据类型的命名空间名IsAbstract指示该类型是否是抽象类型IsArray指示该类型是否是数组IsClass指示该类型是否是类IsEnum指示该类型是否是枚举IsInterface指示该类型是否是接口IsPublic指示该类型是否是公有的IsSealed指示该类型是否是密封类IsValueType指示该类型是否是值类型二、Type类中的常用方法方法描述GetConstructor()返回ConstructorInfo类型用于取得该类的构造函数的信息GetConstructors()返回ConstructorInfo[]类型用于取得该类的所有公共构造函数的信息GetEvent()返回表示指定的公共事件的EventInfo对象。GetEvents()返回当前Type声明或继承的所有公共事件。返回EventInfo[]。GetField()返回FieldInfo类型用于取得该类的字段成员变量的信息GetFields()返回FieldInfo[]类型用于取得该类的所有公共字段成员变量的信息GetInterface()返回InterfaceInfo类型用于取得该类实现的接口的信息GetInterfaces()返回InterfaceInfo[]类型用于取得该类实现的所有接口的信息GetMember()返回MemberInfo类型用于取得该类的所有成员的信息GetMembers()返回MemberInfo[]类型用于取得该类的所有公共成员的信息GetMethod()返回MethodInfo类型用于取得该类的方法的信息GetMethods()返回MethodInfo[]类型用于取得该类的所有公共方法的信息GetProperty(),GetProperties()返回PropertyInfo类型用于取得该类的属性的信息实例代码using System; using System.Reflection; class Example { static void Main() { Type t typeof(String); MethodInfo substr t.GetMethod(Substring, new Type[] { typeof(int), typeof(int) }); Object result substr.Invoke(Hello, World!, new Object[] { 7, 5 }); Console.WriteLine({0} returned \{1}\., substr, result); } } /* This code example produces the following output: System.String Substring(Int32, Int32) returned World. */三、MethodBase.Invoke 方法3.1、重载方法名称说明Invoke(Object, Object[])使用指定的参数调用由当前实例表示的方法或构造函数。Invoke(Object, BindingFlags, Binder, Object[], CultureInfo)在派生类中重写时使用给定参数调用反射的方法或构造函数。3.2、Invoke(Object, Object[])使用指定的参数调用由当前实例表示的方法或构造函数。public object? Invoke(object? obj, object?[]? parameters);参数objObject要对其调用方法或构造函数的对象。 如果方法是静态的则忽略此参数。 如果构造函数是静态的则此参数必须是 null 定义构造函数的类的实例。parametersObject[]已调用的方法或构造函数的参数列表。 这是一个对象数组其数字、顺序和类型与要调用的方法或构造函数的参数相同。 如果没有参数 parameters 应为 null。如果此实例表示的方法或构造函数采用参数 ref ByRef 在 Visual Basic 中则此参数不需要特殊属性才能使用此函数调用方法或构造函数。 未使用值显式初始化的此数组中的任何对象都将包含该对象类型的默认值。 对于引用类型元素此值为 null. 对于值类型元素默认值为 0、0.0 或 false具体取决于特定元素类型。3.3、示例代码下面的代码示例演示了使用反射的动态方法查找。 请注意不能使用 MethodInfo 基类中的对象调用派生类中重写的方法因为后期绑定无法解析重写。using System; using System.Reflection; public class MagicClass { private int magicBaseValue; public MagicClass() { magicBaseValue 9; } public int ItsMagic(int preMagic) { return preMagic * magicBaseValue; } } public class TestMethodInfo { public static void Main() { // Get the constructor and create an instance of MagicClass Type magicType Type.GetType(MagicClass); ConstructorInfo magicConstructor magicType.GetConstructor(Type.EmptyTypes); object magicClassObject magicConstructor.Invoke(new object[]{}); // Get the ItsMagic method and invoke with a parameter value of 100 MethodInfo magicMethod magicType.GetMethod(ItsMagic); object magicValue magicMethod.Invoke(magicClassObject, new object[]{100}); Console.WriteLine(MethodInfo.Invoke() Example\n); Console.WriteLine(MagicClass.ItsMagic() returned: {0}, magicValue); } } // The example program gives the following output: // // MethodInfo.Invoke() Example // // MagicClass.ItsMagic() returned: 900四、ConstructorInfo.Invoke 方法名称说明Invoke(Object[])调用具有指定参数的实例反映的构造函数为不常用的参数提供默认值。Invoke(BindingFlags, Binder, Object[], CultureInfo)在派生类中实现时在指定ConstructorInfo参数的约束下调用由此Binder反射的构造函数。4.1、Invoke(Object[])调用具有指定参数的实例反映的构造函数为不常用的参数提供默认值。public object Invoke(object?[]? parameters);参数parametersObject[]一个值数组该值与此构造函数的参数的参数的数量、顺序和类型在默认绑定器的约束下匹配。 如果此构造函数不采用任何参数则使用包含零个元素的数组或null与 Object[] parameters new Object[0] 中一样。 未使用值显式初始化的此数组中的任何对象都将包含该对象类型的默认值。 对于引用类型元素此值为null. 对于值类型元素此值为 0、0.0 或false具体取决于特定的元素类型。注解数组中parameters元素的数量、类型和顺序应与此实例反映的构造函数的参数的数量、类型和顺序相同。 在调用构造函数之前Invoke请确保调用方具有访问权限并验证参数是否有效。对于完全受信任的代码将忽略访问限制。 也就是说每当完全信任代码时都可以使用反射访问和调用专用构造函数、方法、字段和属性。4.2、Invoke(BindingFlags, Binder, Object[], CultureInfo)在派生类中实现时在指定ConstructorInfo参数的约束下调用由此Binder反射的构造函数。public abstract object Invoke(System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder? binder, object?[]? parameters, System.Globalization.CultureInfo? culture);参数invokeAttrBindingFlagsBindingFlags指定绑定类型的值之一。binderBinder一Binder个定义一组属性并启用使用反射对成员的绑定、强制参数类型和调用成员。binder如果是nullBinder.DefaultBinding则使用。parametersObject[]一个类型Object数组用于匹配此构造函数的参数的数量、顺序和类型其约束为binder。 如果此构造函数不需要参数则传递一个包含零个元素的数组如 Object[] parameters new Object[0]。 未使用值显式初始化的此数组中的任何对象都将包含该对象类型的默认值。 对于引用类型元素此值为null. 对于值类型元素此值为 0、0.0 或false具体取决于特定的元素类型。culture:CultureInfoCultureInfo 用于控制类型的强制转换。如果此值为 null则使用当前线程的 CultureInfo。注解参数数组中元素的数量、类型和顺序应与该实例所反映的构造函数的参数数量、类型和顺序完全一致。在调用构造函数之前Invoke 确保调用者具有访问权限并且参数的数量、顺序和类型均正确。对于完全受信任的代码访问限制将被忽略。也就是说只要代码完全受信任就可以使用反射来访问和调用私有构造函数、方法、字段和属性。