c#中dynamic动态类型与静态成员函数

看《CLR via C#》中动态类型相关内容时,我想到了一个有意思任务:需要实现一个函数DynamicCallStaticMethod,包含四个参数:(dynamic a, dynamic b, Type t, string MethodName),目的是调用t对应的类型的静态成员函数MethodName,并将动态类型a与b作为这个静态成员函数的参数。

例如,假设我定义了某个类型SomeClass,其中包含静态成员函数“Concat",那么我希望在DynamicCallStaticMeghod中调用SomeClass.Concat(a, b)。其中a与b是dynamic的,在运行程序时根据实际类型class1与class2调用SomeClass.Concat对应的重载版本SomeClass.Concat(class1, class2)。当然,如果没有这种重载函数就会运行出错了。

听起来是不是有点蛋疼哈哈哈哈哈哈哈,来吧,给出我的代码:

        static object DynamicCallStaticMethod(dynamic a, dynamic b, Type t, string MethodName)
        { //对动态参数的a与b调用t类型的名为MethodName的静态方法
          //例如,t为typeof(SomeClass),则相当与SomeClass.MethodName(a, b)
          //运行时动态获取a与b的实际类型,然后调用相应的SomeClass.MethodName重载
            Type[] argTypes = new Type[] { a.GetType(), b.GetType() };
            MethodInfo method = t.GetMethod(MethodName, argTypes);
            object[] arguments = new object[] { a, b };
            object result = method.Invoke(null, arguments);
            return result;
        }

我只是看书的过程中突然想到这么个东西,简单的实现了程序,上面这段代码存在一些安全问题。比如如果SomeClass.Concat(class1, class2)的返回类型如果是void那么运行时会报错。

如果想要更完善的版本,大家可以参考一下CLR via C#第五章末尾那个程序。

下面对上面的函数进行测试。

首先定义一个类

    class FunnyClass
    {
        public static object Concat(FunnyClass f1, string s1)
        {
            return "FunnyClass.Concat(FunnyClass, String)";
        }
        public static object Concat(FunnyClass f1, FunnyClass f2)
        {
            return "FunnyClass.Concat(FunnyClass, FunnyClass)";
        }
    }

下面是一个测试函数:

        static void testDynamicCall()
        {
            Console.WriteLine("## test the function 'static object DynamicCallStaticMethod(dynamic a, dynamic b, Type t, string MethodName)'");
            String a = "xxx", b = "yyyy";
            object a_b = DynamicCallStaticMethod(a, b, typeof(String), "Concat");
            Console.WriteLine((string)a_b);
            FunnyClass f1 = new FunnyClass();
            object f1_a = DynamicCallStaticMethod(f1, a, typeof(FunnyClass), "Concat");
            Console.WriteLine((string)f1_a);
            object f1_f1 = DynamicCallStaticMethod(f1, f1, typeof(FunnyClass), "Concat");
            Console.WriteLine((string)f1_f1);

            f1_a = DynamicCallStaticMethod(f1, a, f1.GetType(), "Concat"); #尤其注意这个调用,DynamicCallStaticMethod的第三个参数也根据动态类型对象在运行时才能得知
            Console.WriteLine((string)f1_a);

            Console.WriteLine("## end");
        }

看看运行结果:

可以看到,第一次调用DynamicCallStaticMethod时,其内部调用的是String的静态成员Concat。后三次DynamicCallStaticMethod调用的内部则是使用了自定义类型FunnyClass的静态成员Concat的不同重载形式。

 

实际用途么…暂时我也想不到,不知道可不可以作为c#的面试题。如果有面试官采用或较为直接的借鉴了本文内容,请私信博主支付稿酬。

以上内容纯属博主图一乐,但如果有错误之处,或是更好的实现方法,欢迎大家私信我。如果有朋友提出了我认为有价值的意见,那么我将分你一部分本文稿酬(如果有的话)。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值