zoukankan      html  css  js  c++  java
  • 通过Type.InvokeMethod实现方法的重载

    版本:.NET Framework 3.5

    先来一个反射调用方法的例子:

    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) });
    		// 用MethodBase类的Invoke(object obj, object[] parameters)方法
            Object result = 
                substr.Invoke("Hello, World!", new Object[] { 7, 5 });// 射调用String的Substring(int startIndex, int length)方法
            Console.WriteLine("{0} returned "{1}".", substr, result);
        }
    }
    
    /* 输出:
    System.String Substring(Int32, Int32) returned "World".
     */

    进入正题:通过Type.InvokeMethod实现方法的重载

     1)介绍type

     Type 为 System.Reflection 功能的根,也是访问元数据的主要方式。使用 Type 的成员获取关于类型声明的信息,如构造函数、方法、字段、属性和类的事件,以及在其中部署该类的模块和程序集。
    在多线程方案中,不要锁定 Type 对象以同步对 static 数据的访问。其他不受您控制的代码可能也会锁定您的类类型。这可能会导致死锁。应转而通过锁定私有 static 对象来同步对静态数据的访问。
    这个类是线程安全的;多个线程可以同时从此类型的一个实例读取数据。Type 的实例可表示以下任何类型:

    值类型
    数组
    接口
    指针
    枚举
    构造泛型类型和泛型类型定义
    构造泛型类型、泛型类型定义和泛型方法定义的类型实参和类型形参


     2)实例

    Assembly assembly = Assembly.LoadFrom(sDllName);
    Type fType = assembly.GetType(sClassName);
    object instance = Activator.CreateInstance (fType);
    fType.InvokeMember("classmethod",BindingFlags.InvokeMethod,null,instance,sParams);//调用指定实例instance的classmethod方法,sParams为传入参数,数量不固定,达到方法的重载

    3)扩展

    枚举类BindingFlags各属性含义


    Default 不指定绑定标志。
    IgnoreCase 指定当绑定时不应考虑成员名的大小写。
    DeclaredOnly 指定只应考虑在所提供类型的层次结构级别上声明的成员。不考虑继承成员。
    Instance 指定实例成员将包括在搜索中。
    Static 指定静态成员将包括在搜索中。
    Public 指定公共成员将包括在搜索中。
    NonPublic 指定非公共成员将包括在搜索中。
    FlattenHierarchy 指定应返回层次结构上的公共静态成员和受保护的静态成员。不返回继承类中的私有静态成员。静态成员包括字段、方法、事件和属性。不返回嵌套类型。
    InvokeMethod 指定要调用一个方法。它不能是构造函数或类型初始值设定项。
    CreateInstance 指定“反射”应该创建指定类型的实例。调用与给定参数匹配的构造函数。忽略提供的成员名。如果未指定查找类型,将应用 (Instance |Public)。调用类型初始值设定项是不可能的。
    GetField 指定应返回指定字段的值。
    SetField 指定应设置指定字段的值。
    GetProperty 指定应返回指定属性的值。
    SetProperty 指定应设置指定属性的值。对于 COM 属性,指定此绑定标志与指定 PutDispProperty 和 PutRefDispProperty 是等效的。
    PutDispProperty 指定应调用 COM 对象的 PROPPUT 成员。PROPPUT 指定使用值的属性设置函数。如果属性同时具有 PROPPUT 和 PROPPUTREF,而且需要区分调用哪一个,请使用 PutDispProperty。
    PutRefDispProperty 指定应调用 COM 对象的 PROPPUTREF 成员。PROPPUTREF 指定使用引用而不是值的属性设置函数。如果属性同时具有 PROPPUT 和 PROPPUTREF,而且需要区分调用哪一个,请使用 PutRefDispProperty。
    ExactBinding 指定提供参数的类型必须与对应形参的类型完全匹配。如果调用方提供一个非空 Binder 对象,则“反射”将引发异常,因为这意味着调用方正在提供的 BindToXXX 实现将选取适当的方法。
    SuppressChangeType 未实现。
    OptionalParamBinding 返回其参数计数与提供参数的数目匹配的成员集。此绑定标志用于所带参数具有默认值的方法和带变量参数 (varargs) 的方法。此标志应只与 Type.InvokeMember 一起使用。
    IgnoreReturn 在 COM interop 中用于指定可以忽略成员的返回值。

    举例

    using System;
    using System.Reflection;
    using System.IO;
    
    namespace BindingFlagsSnippet
    {
        class EntryPoint
        {
            static void Main(string[] args)
            {
                Invoke.Go();
            }
        }
    
    
        class Invoke
        {
            public static void Go()
            {
                // BindingFlags.InvokeMethod
                // Call a static method.
                Type t = typeof (TestClass);
    
                Console.WriteLine();
                Console.WriteLine("Invoking a static method.");
                Console.WriteLine("-------------------------");
                t.InvokeMember ("SayHello", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new object [] {});
    
                // BindingFlags.InvokeMethod
                // Call an instance method.
                TestClass c = new TestClass ();
                Console.WriteLine();
                Console.WriteLine("Invoking an instance method.");
                Console.WriteLine("----------------------------");
                c.GetType().InvokeMember ("AddUp", BindingFlags.InvokeMethod, null, c, new object [] {});
                c.GetType().InvokeMember ("AddUp", BindingFlags.InvokeMethod, null, c, new object [] {});
    
                // BindingFlags.InvokeMethod
                // Call a method with parameters.
                object [] args = new object [] {100.09, 184.45};
                object result;
                Console.WriteLine();
                Console.WriteLine("Invoking a method with parameters.");
                Console.WriteLine("---------------------------------");
                result = t.InvokeMember ("ComputeSum", BindingFlags.InvokeMethod, null, null, args);
                Console.WriteLine ("{0} + {1} = {2}", args[0], args[1], result);
    
                // BindingFlags.GetField, SetField
                Console.WriteLine();
                Console.WriteLine("Invoking a field (getting and setting.)");
                Console.WriteLine("--------------------------------------");
                // Get a field value.
                result = t.InvokeMember ("Name", BindingFlags.GetField, null, c, new object [] {});
                Console.WriteLine ("Name == {0}", result);
                // Set a field.
                t.InvokeMember ("Name", BindingFlags.SetField, null, c, new object [] {"NewName"});
                result = t.InvokeMember ("Name", BindingFlags.GetField, null, c, new object [] {});
                Console.WriteLine ("Name == {0}", result);
    
                Console.WriteLine();
                Console.WriteLine("Invoking an indexed property (getting and setting.)");
                Console.WriteLine("--------------------------------------------------");
                // BindingFlags.GetProperty
                // Get an indexed property value.
                int  index = 3;
                result = t.InvokeMember ("Item", BindingFlags.GetProperty, null, c, new object [] {index});
                Console.WriteLine ("Item[{0}] == {1}", index, result);
                // BindingFlags.SetProperty
                // Set an indexed property value.
                index = 3;
                t.InvokeMember ("Item", BindingFlags.SetProperty, null, c, new object [] {index, "NewValue"});
                result = t.InvokeMember ("Item", BindingFlags.GetProperty , null, c, new object [] {index});
                Console.WriteLine ("Item[{0}] == {1}", index, result);
    
                Console.WriteLine();
                Console.WriteLine("Getting a field or property.");
                Console.WriteLine("----------------------------");
                // BindingFlags.GetField
                // Get a field or property.
                result = t.InvokeMember ("Name", BindingFlags.GetField | BindingFlags.GetProperty, null, c, new object [] {});
                Console.WriteLine ("Name == {0}", result);
                // BindingFlags.GetProperty
                result = t.InvokeMember ("Value", BindingFlags.GetField | BindingFlags.GetProperty, null, c, new object [] {});
                Console.WriteLine ("Value == {0}", result);
    
                Console.WriteLine();
                Console.WriteLine("Invoking a method with named parameters.");
                Console.WriteLine("---------------------------------------");
                // BindingFlags.InvokeMethod
                // Call a method using named parameters.
                object[] argValues = new object [] {"Mouse", "Micky"};
                String [] argNames = new String [] {"lastName", "firstName"};
                t.InvokeMember ("PrintName", BindingFlags.InvokeMethod, null, null, argValues, null, null, argNames);
    
                Console.WriteLine();
                Console.WriteLine("Invoking a default member of a type.");
                Console.WriteLine("------------------------------------");
                // BindingFlags.Default
                // Call the default member of a type.
                Type t3 = typeof (TestClass2);
                t3.InvokeMember ("", BindingFlags.InvokeMethod | BindingFlags.Default, null, new TestClass2(), new object [] {});
    
                // BindingFlags.Static, NonPublic, and Public
                // Invoking a member by reference.
                Console.WriteLine();
                Console.WriteLine("Invoking a method by reference.");
                Console.WriteLine("-------------------------------");
                MethodInfo m = t.GetMethod("Swap");
                args = new object[2];
                args[0] = 1;
                args[1] = 2;
                m.Invoke(new TestClass(),args);
                Console.WriteLine ("{0}, {1}", args[0], args[1]);
                // The string is case-sensitive.
                Type type = Type.GetType("System.String");
    
                // Check to see if the value is valid. If the object is null, the type does not exist.
                if (type == null)
                {
                    Console.WriteLine("Please ensure that you specify only valid types in the type field.");
                    Console.WriteLine("The type name is case-sensitive.");
                    return;
                }
                // Declare and populate the arrays to hold the information.
                // You must declare either NonPublic or Public with Static or the search will not work.
                FieldInfo [] fi = type.GetFields (BindingFlags.Static |
                    BindingFlags.NonPublic | BindingFlags.Public);
                // BindingFlags.NonPublic
                MethodInfo [] miNonPublic = type.GetMethods (BindingFlags.Static |
                    BindingFlags.NonPublic);
                // BindingFlags.Public
                MethodInfo [] miPublic = type.GetMethods (BindingFlags.Static |
                    BindingFlags.Public);
    
                // Iterate through all the nonpublic methods.
                foreach (MethodInfo method in miNonPublic)
                {
                    Console.WriteLine(method);
                }
                // Iterate through all the public methods.
                foreach (MethodInfo method in miPublic)
                {
                    Console.WriteLine(method);
                }
                // Iterate through all the fields.
                foreach (FieldInfo f in fi)
                {
                    Console.WriteLine(f);
                }
    
                // BindingFlags.Instance
                // Call an instance method.
                TestClass tc = new TestClass ();
                Console.WriteLine();
                Console.WriteLine("Invoking an Instance method.");
                Console.WriteLine("----------------------------");
                tc.GetType().InvokeMember ("AddUp", BindingFlags.Public |
                    BindingFlags.Instance | BindingFlags.CreateInstance,
                    null, tc, new object [] {});
    
                // BindingFlags.CreateInstance
                // Calling and creating an instance method.
                Console.WriteLine();
                Console.WriteLine("Invoking and creating an instance method.");
                Console.WriteLine("-----------------------------------------");
                tc.GetType().InvokeMember ("AddUp", BindingFlags.Public |
                    BindingFlags.Instance | BindingFlags.CreateInstance,
                    null, tc, new object [] {});
    
                // BindingFlags.DeclaredOnly
                TestClass tc2 = new TestClass();
                Console.WriteLine();
                Console.WriteLine("DeclaredOnly members");
                Console.WriteLine("---------------------------------");
                System.Reflection.MemberInfo[] memInfo =
                    tc2.GetType().GetMembers(BindingFlags.DeclaredOnly);
                for(int i=0;i<memInfo.Length;i++)
                {
                    Console.WriteLine(memInfo[i].Name);
                }
    
                // BindingFlags.SuppressChangeType
                TestClass obj = new TestClass();
                Console.WriteLine();
                Console.WriteLine("Invoking static method - PrintName");
                Console.WriteLine("---------------------------------");
                System.Reflection.MethodInfo methInfo =
                    obj.GetType().GetMethod("PrintName");
                methInfo.Invoke(obj,BindingFlags.SuppressChangeType |
                    BindingFlags.InvokeMethod, null,new object[]
                    {"Brad","Smith"},null);
    
                // BindingFlags.IgnoreCase
                Console.WriteLine();
                Console.WriteLine("Using IgnoreCase and invoking the PrintName method.");
                Console.WriteLine("---------------------------------------------------");
                methInfo = obj.GetType().GetMethod("PrintName");
                methInfo.Invoke(obj,BindingFlags.IgnoreCase |
                    BindingFlags.InvokeMethod, null,new object[]
                    {"brad","smith"},null);
    
                // BindingFlags.IgnoreReturn
                Console.WriteLine();
                Console.WriteLine("Using IgnoreReturn and invoking the PrintName method.");
                Console.WriteLine("-----------------------------------------------------");
                methInfo = obj.GetType().GetMethod("PrintName");
                methInfo.Invoke(obj,BindingFlags.IgnoreReturn |
                    BindingFlags.InvokeMethod, null,new object[]
                    {"Brad","Smith"},null);
    
                // BindingFlags.OptionalParamBinding
                Console.WriteLine();
                Console.WriteLine("Using OptionalParamBinding and invoking the PrintName method.");
                Console.WriteLine("-------------------------------------------------------------");
                methInfo = obj.GetType().GetMethod("PrintName");
                methInfo.Invoke(obj,BindingFlags.OptionalParamBinding |
                    BindingFlags.InvokeMethod, null,new object[]
                    {"Brad","Smith"},null);
    
                // BindingFlags.ExactBinding
                Console.WriteLine();
                Console.WriteLine("Using ExactBinding and invoking the PrintName method.");
                Console.WriteLine("-----------------------------------------------------");
                methInfo = obj.GetType().GetMethod("PrintName");
                methInfo.Invoke(obj,BindingFlags.ExactBinding |
                    BindingFlags.InvokeMethod, null,new object[]
                    {"Brad","Smith"},null);
    
                // BindingFlags.FlattenHierarchy
                Console.WriteLine();
                Console.WriteLine("Using FlattenHierarchy and invoking the PrintName method.");
                Console.WriteLine("---------------------------------------------------------");
                methInfo = obj.GetType().GetMethod("PrintName");
                methInfo.Invoke(obj,BindingFlags.FlattenHierarchy |
                    BindingFlags.InvokeMethod, null,new object[]
                    {"Brad","Smith"},null);
            }
        }




  • 相关阅读:
    day09
    day08
    day05
    day04
    day03
    day02
    LogCat查看Android运行日志
    ADT+SDK,Android开发环境搭建问题
    第二次冲刺周期第十天
    第二次冲刺周期第九天
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3143075.html
Copyright © 2011-2022 走看看