C# 反射执行指定方法名/重载

Type.InvokeMember 方法

1. 主方法

class Program
{
    static void Main(string[] args)       
    {
        ReflectUtils rf = new ReflectUtils();
        rf.FNCMethod("ToString", null);//执行类中重写的ToString()方法
        rf.FNCMethod("PrintNoPara", null);//执行无参方法PrintNoPara
        rf.FNCMethod("PrintStatic", new object[] { "...PrintStatic" });//执行带一个参数静态方法PrintStatic
        rf.FNCMethod("DoSthOnePara", new object[] { "...DoSthOnePara" });//执行带一个带参方法DoSthOnePara
        rf.FNCMethod("DoSthTwoPara", new object[] { "...DoSthTwoPara", 3});//执行带两个个带参方法DoSthTwoPara
    }
}

2. 中间类,执行ItemMethod 中的方法。可根据需要新增配置其他执行方法。

 class ReflectUtils
    {
        public void FNCMethod(string methodName, object[] para)
        {
            ItemMethod iMethod = new ItemMethod();
            iMethod.MethodCode(methodName, para);
        }
    }

3. 通过MethodCode,执行当前类中传入带参(para)的指定方法(methodName)

class ItemMethod
    {
        #region 测试用例
        public ItemMethod()
        {
            Console.WriteLine("ctor:no para");
        }
        public ItemMethod(string x)
        {
            Console.WriteLine("ctor:string para");
        }
        Int32 myField;
        public ItemMethod(ref Int32 x)
        {
            x *= 5;
        }
        public override String ToString()
        {
            Console.WriteLine("override ToString");
            return myField.ToString();
        }
        public static void PrintNoPara()
        {
            Console.WriteLine("PrintNoPara");
        }
        public static void PrintStatic(string stm)
        {
            Console.WriteLine("PrintStatic:{0}", stm);
        }
        public void PrintNotStatic(string stm)
        {
            Console.WriteLine("PrintNotStatic:{0}", stm);
        }
        public void DoSthOnePara(string sth)
        {
            Console.WriteLine("DoSthOnePara:{0}", sth);
        }
        public void DoSthTwoPara(string sth, int ct)
        {
            Console.WriteLine("DoSth:{0},{1}", sth, ct);
        }
        public Int32 MyProp
        {
            get { return myField; }
            set
            {
                if (value < 1)
                    throw new ArgumentOutOfRangeException("value", value, "value must be > 0");
                myField = value;
            }
        } 
        #endregion

        internal void MethodCode(string methodName, object[] para)
        {
            Assembly assembly = Assembly.LoadFile(Assembly.GetExecutingAssembly().Location);
            string classTypeFullName = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName;
            Type classType = assembly.GetType(classTypeFullName);
            ////创建实例,此方式要求实例类型必须有无参构造函数
            //object classInstance = assembly.CreateInstance(classTypeFullName);

            // 创建实例2.根据指定参数(args)执行对应构造函数。null执行无参构造函数
            Object[] args = new Object[] { "ara1" };
            Console.WriteLine("构造函数执行前x值:{0}.", args[0]);
            Object classInstance = classType.InvokeMember(null,
                BindingFlags.DeclaredOnly |
                BindingFlags.Public | BindingFlags.NonPublic |
                BindingFlags.Instance | BindingFlags.CreateInstance, null, null, args);
            Console.WriteLine("Type: " + classInstance.GetType().ToString());
            Console.WriteLine("构造函数执行后x值:{0}.", args[0]);


            #region 读取、写入字段.
            classType.InvokeMember("myField",
                    BindingFlags.DeclaredOnly |
                    BindingFlags.Public | BindingFlags.NonPublic |
                    BindingFlags.Instance | BindingFlags.SetField, null, classInstance, new Object[] { 5 });
            Int32 v = (Int32)classType.InvokeMember("myField",
                BindingFlags.DeclaredOnly |
                BindingFlags.Public | BindingFlags.NonPublic |
                BindingFlags.Instance | BindingFlags.GetField, null, classInstance, null);
            Console.WriteLine("myField: " + v); 
            #endregion

            //classType.GetMethod(methodName).IsStatic 判断是否静态
            // 静态方法可以不传target(类型的实例)参数。非静态方法要求必须提供target(类型的实例)参数.
            classType.InvokeMember(methodName, BindingFlags.InvokeMethod, null, classInstance, para);

            #region 读取、写入属性。首先,尝试分配一个无效的值;然后分配一个有效的值;最后,获取值。
            try
            {
                // 分配值 0 给 MyProp属性,属性抛出异常,因为set判断必须 > 0 。
                // InvokeMember 获取异常,并抛出一个 TargetInvocationException异常。
                // 要查看异常详细信息,要catch 下TargetInvocationException,并检查 inner exception.                 
                classType.InvokeMember("MyProp",
                    BindingFlags.DeclaredOnly |
                    BindingFlags.Public | BindingFlags.NonPublic |
                    BindingFlags.Instance | BindingFlags.SetProperty, null, classInstance, new Object[] { 0 });
            }
            catch (TargetInvocationException e)
            {
                // 如果属性因一些其他意外分配失败,抛出 TargetInvocationException异常。
                if (e.InnerException.GetType() !=typeof(ArgumentOutOfRangeException))
                    throw;
                Console.WriteLine("给MyProp分配的值无效:{0}",e.InnerException);
            }
            classType.InvokeMember("MyProp",
                BindingFlags.DeclaredOnly |
                BindingFlags.Public | BindingFlags.NonPublic |
                BindingFlags.Instance | BindingFlags.SetProperty, null, classInstance, new Object[] { 2 });
            v = (Int32)classType.InvokeMember("MyProp",
                BindingFlags.DeclaredOnly |
                BindingFlags.Public | BindingFlags.NonPublic |
                BindingFlags.Instance | BindingFlags.GetProperty, null, classInstance, null);
            Console.WriteLine("MyProp: " + v); 
            #endregion
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值