C#通过反射给代理赋值

问题说明

  我们单位开发的程序,除了在我们本单位(单位A)使用之外,还在其它单位(单位B)使用,区别就是我们单位一直在更新服务端的接口,但是B单位是很久才更新一次。因此在我们单位和单位B中服务的接口不一样。最近碰到一个问题,有个函数,假设名称为FuncCalcu,在我们单位的服务中有该函数,在单位B中没有这个函数。在客户端使用时,使用全局类中的变量IsExistedFuncCalcu来判断是否要调用FuncCalcu,调用代码类似于下面:

if(IsExistedFuncCalcu)
{
	FunCalcu();
}

在这里插入图片描述
但是实际代码在B单位运行时,会报在服务端引用程序集中无法找到函数FunCalcu,即使在代码运行过程中没有调到FuncCalcu函数,也会报这个错。错误还原的示例程序在https://github.com/guochao2299/DelegateInvokeTest/tree/master/DelegateInvokeTest/%E9%97%AE%E9%A2%98%E8%BF%98%E5%8E%9F%E4%BB%A3%E7%A0%81中可以找到。即便不会调用该函数,运行程序时依然会报错:
在这里插入图片描述

原因分析

  通过对代码进行调试分析,发现即便没有直接调用函数FunCalcu,如下面代码所示,在调用DoTheOperation时,即便时没有使用MathLib.Sub函数,程序也会检查引用的程序集中是否包含MathLib.Sub函数,如果不包含,就会报错。

        private float DoTheOperation(int a,int b,int optType)
        {
            switch(optType)
            {
                case 0:
                    return MathCalcLib.MathLib.Add(a , b);

                case 1:
                    if (MathCalcLib.MathLib.IsSupportSubOpt)
                    {
                        return MathCalcLib.MathLib.Sub(a, b);
                    }

                    break;

                case 2:
                    return MathCalcLib.MathLib.Multy(a, b);

                case 3:
                    return MathCalcLib.MathLib.Div(a, b);
            }

            throw new Exception("未识别的操作符");
        }
解决方案

  为了防止应用系统报错,可以采用反射的方式调用Sub函数,这样即便程序集中不包含Sub函数,程序在运行过程中也不会报错,示例代码如下所示:

					if (MathCalcLib.MathLib.IsSupportSubOpt)
                    {
                        System.Reflection.MethodInfo mInfo = typeof(MathCalcLib.MathLib).GetMethod("Sub", System.Reflection.BindingFlags.Static);
                        if(mInfo==null)
                        {
                            MessageBox.Show("MathCalcLib.MathLib类中不包含静态函数Sub");
                            return;
                        }

                        return (float)mInfo.Invoke(null, new object[] { a, b });
                    }

  反射的方式可以避免因为某个函数不存在导致程序出现异常,但是还有其它方式可以避免出错,例如使用代理方式,也即采用反射方式给代理赋值,如果存在函数Sub,则将Sub函数赋值给代理,如果不存在,则给代理赋默认值,代码如下所示,至此问题解决:

                   if (MathCalcLib.MathLib.IsSupportSubOpt)
                    {
                        System.Reflection.MethodInfo mInfo = typeof(MathCalcLib.MathLib).GetMethod("Sub", System.Reflection.BindingFlags.Public| System.Reflection.BindingFlags.Static);
                        if (mInfo == null)
                        {
                            MessageBox.Show("MathCalcLib.MathLib类中不包含静态函数Sub");
                        }

                        Delegate d= Delegate.CreateDelegate(typeof(Func<int, int, float>), mInfo);
                        result = d as Func<int, int, float>;
                        break;
                    }
                    else
                    {
                        result = delegate (int a, int b)
                          {
                              return 0;
                          };
                    }

完整的测试代码放在了如下网址中:
https://github.com/guochao2299/DelegateInvokeTest/upload/DelegateVersion

参考文献:
[1]https://blog.csdn.net/soapcoder92/article/details/51027547
[2]https://blog.csdn.net/lxrj2008/article/details/61255224

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值