• C#里的var和dynamic区别到底是什么,你真的搞懂了嘛


    前言

    这个var和dynamic都是不确定的初始化类型,但是这两个本质上的不同。不同在哪儿呢?var编译阶段确定类型,dynamic运行时阶段确定类型。这种说法对不对呢?本篇看下,文章原文地址:在这里

    概括

    以下详细叙述下这两个(var,dynamic)上下文关键字的不同点。
    1.例子

    static void Main(string[] args)
    {
       var a = 0x10;
       dynamic b = 0x10;
    }
    

    var其实在你设置它的变量a的值的那一刻起,它的类型就确定了。这点你可以在VS里,在var上面查看定义,就可以看到例子里面a的类型就是Int32。如果你把变量a赋值为字符串类型,那么它变量a的类型就是string。严格来说还没到编译阶段,在编译器VS里面就被识别了类型。
    而dynamic则不同,它类似于public,static。无法查看其实际类型,但是这里注意了dynamic和var同称之为:上下文关键字(官方说法是在代码中提供特殊含义)。也就是说它们两个在C#里面严格来说都是关键字。只不过运作模式不同而已。

    2.IL Code

    .method private hidebysig static void  Main(string[] args) cil managed
    {
      .locals init (int32 V_0,
               object V_1)
      IL_0000:  nop
      IL_0001:  ldc.i4.s   16
      IL_0003:  stloc.0
      IL_0004:  ldc.i4.s   16
      IL_0006:  box        [System.Runtime]System.Int32
      IL_000b:  stloc.1
      IL_000c:  ret
    } // end of method Program::Main
    

    在IL里面,var的操作模式是:将0x10(十进制的16)推送到堆上,然后从堆里面取出来赋值给a。dynamic的操作模式是:将0x10推送到堆上,然后从堆上取出来作为参数传递给box函数。这里可以看到很明显的不同。当然IL依然远远不够。所以下面我们上JIT。

    3.ASM Code

    var a=0x10
    00007FF9FC1A76DC  mov         dword ptr [rbp+3Ch],10h  
    
    dynamic b=0x10
    00007FF9FC1A76E3  mov         rcx,7FF9FC10E8D0h  
    00007FF9FC1A76ED  call        CORINFO_HELP_NEWSFAST (07FFA5BCA0000h)  
    00007FF9FC1A76F2  mov         qword ptr [rbp+28h],rax  
    00007FF9FC1A76F6  mov         rax,qword ptr [rbp+28h]  
    00007FF9FC1A76FA  mov         dword ptr [rax+8],10h  
    00007FF9FC1A7701  mov         rax,qword ptr [rbp+28h]  
    00007FF9FC1A7705  mov         qword ptr [rbp+30h],rax  
    

    可以看到dynamic的code远比var的code夸张,而且性能也是成问题的。它这里调用了CORINFO_HELP_NEWSFAST,实际上是进行了一个装箱,也就是IL的box,运行时里面的JIT_New。先传入参数,然后返回装箱后的对象地址也就是MethodTable,最后把0x10放入到&Methodtable+8地方。而var只是直接把0x10放入到栈。这么看来,如果有性能需求,还是建议var,而慎用dynamic。

    4.总结:
    var和dynamic的不同点。
    1.var被rosyln编译前就确定了类型,而dynamic则是在CLR(这里更严格点应该说是在JIT)里面确定。
    2.var只是一个简单的值,而dynamic则被实例化成了一个对象,它的变量值是它对象的字段
    3.var的性能远远大于dynamic的性能。


    结尾

    作者:江湖评谈
    欢迎关注我的公众号:江湖评谈(jianghupt),文章首发。
    image

  • 相关阅读:
    【GD32F310开发板试用】Keil编程环境配置、避坑
    Redis常用命令
    【计算机视觉】MoCo v3 讲解
    『网易实习』周记(三)
    基于Java微信小程序民宿短租系统设计和实现(源码+LW+调试文档+讲解等)
    06【对象的扩展】
    如何清理 mac 磁盘?快速清理小妙招在这里
    成人专升本
    【React源码】(十二)Hook源码分析 状态与副作用
    使用API接口获取商品数据:从入门到实践
  • 原文地址:https://www.cnblogs.com/tangyanzhi1111/p/17478648.html