前言

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

概括

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

1.例子

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

var其实在你设置它的变量a的值的那一刻起,它的类型就确定了。这点你可以在VS里,在var上面f12查看定义,就可以看到例子里面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),文章首发。

C#里的var和dynamic区别到底是什么,你真的搞懂了嘛的更多相关文章

  1. 别再人云亦云了!!!你真的搞懂了RDD、DF、DS的区别吗?

    几年前,包括最近,我看了各种书籍.教程.官网.但是真正能够把RDD.DataFrame.DataSet解释得清楚一点的.论据多一点少之又少,甚至有的人号称Spark专家,但在这一块根本说不清楚.还有国 ...

  2. 简述C#中关键字var和dynamic的区别

    C#中关键字var和dynamic的区别如下: 1.var申明的变量必须初始化,dynamic申明的变量无需初始化. 2.var关键字只能在方法内部申明局部变量,dynamic关键字可用于局部变量,字 ...

  3. var, object, dynamic的区别以及使用(转载)

    var, object, dynamic的区别以及使用 阅读目录: 一. 为什么是它们三个 二. 能够任意赋值的原因 三. dynamic的用法 四. 使用dynamic的注意事项 拿这三者比较的原因 ...

  4. var, object, dynamic的区别以及dynamic的使用

    var, object, dynamic的区别以及dynamic的使用 理解C# 4 dynamic(1) - var, object, dynamic的区别以及dynamic的使用 2013-06- ...

  5. var, object, dynamic的区别以及使用

    var, object, dynamic的区别以及使用 阅读目录: 一. 为什么是它们三个 二. 能够任意赋值的原因 三. dynamic的用法 四. 使用dynamic的注意事项 拿这三者比较的原因 ...

  6. Var与Dynamic的区别

    1.var与dynamic的区别   C#中的很多关键词用法比较容易混淆,var和dynamic就是其中一组,但其实它们是有本质的区别的.var 在编译阶段已经确定类型,在初始化时候,必须提供初始化的 ...

  7. var和dynamic的区别及如何正确使用dynamic ?

    C#中的很多关键词用法比较容易混淆,var和dynamic就是其中一组,他们都可以申明动态类型的变量,但是本质上他们还是有不少区别的.var 在编译阶段已经确定类型,在初始化时候,必须提供初始化的值, ...

  8. C#4.0中var和dynamic的区别

    1. var表示“变量的类型是在编译时决定的”, var让你在初始化变量时少输入一些字,编译器会根据右值来推断出变量的类型, var只能用于局部变量的定义,你不能把类的属性定义成 var,也不能把方法 ...

  9. c# 把一个匿名对象赋值给一个Object类型的变量后,怎么取这个变量? c# dynamic动态类型和匿名类 详解C# 匿名对象(匿名类型)、var、动态类型 dynamic 深入浅析C#中的var和dynamic

    比如有一个匿名对象,var  result =......Select( a=>new {  id=a.id, name=a.name});然后Object  obj =  result ;我怎 ...

  10. JavaScript 中定义变量时有无var声明的区别

    关于JavaScript中定义变量时有无var声明的区别 var a=5; //正确 a=5; //正确 在javascript中,以上两种方法都是定义变量的正确方法.微软的Script56.CHM中 ...

随机推荐

  1. Knockin' On PHP's Door ---PHP入门必知(持续更新)

    1.->.=> 和 :: 区别: ::   类中调用静态方法时用->  类中调用属性和非静态方法=> 是键值对,比如在关联数组中用 $arr = ["name&quo ...

  2. 逍遥自在学C语言 | 变量、常量与数据类型

    前言 一.人物简介 第一位闪亮登场,有请今后会一直教我们C语言的老师 -- 自在. 第二位上场的是和我们一起学习的小白程序猿 -- 逍遥. 二.基本数据类型 1.整型 C语言中的整型数据如下表所示: ...

  3. 基于Labelstudio的UIE半监督智能标注方案(本地版)

    基于Labelstudio的UIE半监督智能标注方案(本地版) 更多技术细节参考上一篇项目,本篇主要侧重本地端链路走通教学,提速提效: 基于Labelstudio的UIE半监督深度学习的智能标注方案( ...

  4. [Java]排序算法>交换排序>【冒泡排序】(O(N*N)/稳定/N较小/有序/顺序+链式)

    1 冒泡排序 1.1 算法思想 交换排序的基本思想:两两比较待排序记录的关键字,一旦发现2个记录不满足次序要求时,则:进行交换,直到整个序列全部满足要求为止. 1.2 算法特征 属于[交换排序] 冒泡 ...

  5. 写一个 Hello SpringBoot2 项目

    需求:向浏览发送/hello请求,并响应 Hello,Spring Boot 2 解决: 项目目录:controller层.Main启动项.pom.xml controller层:写好逻辑跳转,当浏览 ...

  6. day32:进程&进程join&守护进程deamon

    目录 1.进程的基本概念 2.进程初体验 3.join:先子后主 4.守护进程:deamon 5.使用自定义类的方式创建进程 6.两张和进程相关的图 进程的基本概念 什么是进程? 进程就是正在运行的程 ...

  7. 基于DotNetCoreNPOI封装特性通用导出excel

    基于DotNetCoreNPOI封装特性通用导出excel 目前根据项目中的要求,支持列名定义,列索引排序,行合并单元格,EXCEL单元格的格式也是随着数据的类型做对应的调整. 效果图: 调用方式 可 ...

  8. C# 获取指定窗口的上层窗口

    如何获取当前窗口层级上方的所有窗口信息 User32有函数GetWindow function (winuser.h) - Win32 apps | Microsoft Docs,可以根据已知窗口句柄 ...

  9. cf1774f解题报告

    Magician and Pigs 分析一下三个操作分别干了些什么 新添一只猪 使血量为 \(x\) 的猪血量变为 \(\max(x-v,0)\) 设前面操作后猪总共会受到 \(s\) 的伤害,复制一 ...

  10. 使用require.context实现优雅的预加载

    前言 在前端开发中,对页面花里胡哨度[注1]要求越高的页面,用到的图片.音频什么的就越多,比如什么结婚请柬.展会请柬.发布会宣传页.数据大屏.虽然现在浏览器不允许网页在没有用户交互的情况下播放音频,但 ...