C#里的var和dynamic區(qū)別到底是什么,你真的搞懂了嘛
當前位置:點晴教程→知識管理交流
→『 技術文檔交流 』
前言var和dynamic都是不確定的類型,但是這兩個有本質(zhì)上的不同。不同在哪兒呢?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推送到堆上,然后從堆上取出來作為參數(shù)傳遞給box函數(shù)。這里可以看到很明顯的不同。當然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夸張,而且性能也是成問題的。它這里調(diào)用了CORINFO_HELP_NEWSFAST實際上是進行了一個裝箱,也就是IL的box,運行時里面的JIT_New。先放入堆,然后返回裝箱后的對象,最后放入棧。這么看來,如果有性能需求,還是建議var,而慎用dynamic。 4.總結(jié): 該文章在 2023/6/17 8:56:36 編輯過 |
關鍵字查詢
相關文章
正在查詢... |