C#中dynamic的正确用法

       C#是类型安全的编程语言。意味着所有表达式都解析成类型的实例,编译器生成的代码只执行对该类型有效的操作。dynamic的出现让C#具有了弱语言类型的特性,有利于处理需要在运行时才会知晓的信息,如果写的是纯C#应用程序,只有在使用反射的时候,才需要和运行时才能确定的信息打交道。编译器在编译的时候不再对类型进行检查,编译期默认dynamic对象支持你想要的任何特性。

       var关键字和dynamic做比较。实际上,var和dynamic完全是两个概念,var实际上是编译器抛给我们的“语法糖”,一旦被编译,编译器会自动匹配var 变量的实际类型,并用实际类型来替换该变量的声明,这看上去就好像我们在编码的时候是用实际类型进行声明的。而dynamic被编译后,实际是一个object类型,只不过编译器会对dynamic类型进行特殊处理,让它在编译期间不进行任何的类型检查,而是将类型检查放到了运行期。

class Program
    {
        static void Main(string[] args)
        {
            //与var不同,声明时不需要初始化
            dynamic value;
            for (int i = 0; i < 2; i++)
            {
                value = (i == 0) ? (dynamic)12 : (dynamic)"X";
                Console.WriteLine(value);
            }
            Console.ReadKey();
        }
    }

       这从visual studio的编辑器窗口就能看出来。以var声明的变量,支持“智能感知”,因为visual studio能推断出var类型的实际类型,而以dynamic声明的变量却不支持“智能感知”,因为编译器对其运行期的类型一无所知。对dynamic变量使用“智能感知”,会提示“此操作将在运行时解析”。

       关于dynamic变量是一个object变量这一点,可以通过IL代码得到验证。当然,编译器也对dynamic声明进行了处理,以区别直接object变量。

      如果字段、方法参数或方法返回值的类型是dynamic,编译器会将类型转换为System.Object,并在元数据中间字段、参数或返回类型应用System.Runtime.CompilerServices.DynamicAttribute的实例。如果局部变量被指定为dynamic,变量类型也会成为Object,但不会向局部变量应用DynamicAttribute,因为它限制在方法内部使用。由于dynamic其实就是object,所以方法签名不能仅靠dynamic和Object的变化来区分。

     所有表达式都能隐式转型为dynamic,因为所有表达式最终都生成从Object派生的类型。从Dynamic转型为其他类型时,虽然编译器允许省略显示转型,但CLR会在运行时验证转型来确定类型安全性。

            {
                //即将要匹配的对象
                object target = "xu shuai";
                //即将要匹配的参数
                object arg = "shu";
                //在目标上查找和希望的实参类型匹配的方法,匹配没有,则返回null
                Type[] types = new Type[] { arg.GetType() };
                MethodInfo method = target.GetType().GetMethod("Contains", types);
                //在目标上调用方法,传递希望的实参
                if (method != null)
                {
                    object[] arguments = new object[] { arg };
                    Boolean res = Convert.ToBoolean(method.Invoke(target, arguments));
                    Console.WriteLine(res);
                }
                else
                {
                    Console.WriteLine("");
                }
            }
            {
                //使用dynamic
                dynamic target = "xu shuai";
                dynamic arg = "shu";
                Boolean re = target.Contains(arg);
                Console.WriteLine(re);
            }

      Dynamic的一个限制是只能访问对象的实例成员,因为dynamic变量必须引用对象。但有时需要动态调用运行时才能确定的一个类型的静态成员。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值