4

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

 1 year ago
source link: https://www.cnblogs.com/tangyanzhi1111/p/17478648.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK