首页 > 编程语言 >浅谈C#中动态类型与值类型装拆箱问题

浅谈C#中动态类型与值类型装拆箱问题

时间:2023-05-05 22:45:43浏览次数:38  
标签:拆箱 浅谈 C# object 封箱 开箱 类型 动态

C#中的值类型封箱、开箱与动态类型的关系

封箱和开箱是C#中两个重要的概念,它们涉及到值类型和引用类型在编译七和运行时的处理方式。动态类型是C# 4.0引入的一个新特性,它允许在编译时不指定类型,而在运行时动态绑定类型。本文将简要介绍封箱、开箱和动态类型的概念,以及装拆箱与动态类型之间的关系。

值类型和引用类型

C#有两种类型:值类型和引用类型。值类型存储在栈上或嵌入在包含类型中,它们直接保存数据值本身。引用类型存储在堆上,它们保存对数据的引用地址。值类型包括所有数值类型、char、bool、enum、struct和record struct。引用类型包括string、object、dynamic、class、record class、interface、delegate和array。

封箱

封箱是将值类型转换为object类型或由该值类型实现的任何接口类型的过程。当CLR对值类型进行封箱时,它会在堆上创建一个新的对象,并将值复制到其中。封箱的过程是隐式的;当一个值类型被赋值给一个object或接口类型的变量时,就会自动发生封箱。

例如:

int x = 10; // 值类型
object y = x; // 封箱

封箱也会发生在将一个值类型传递给一个期望object或接口参数的方法,或者从这样的方法返回一个值类型时。

封箱有一些性能影响,因为它涉及到在堆上分配内存和复制数据。它也给垃圾回收器带来了更多的工作,因为它必须回收不再需要的封箱对象。

开箱

开箱是封箱的逆过程。它是将object类型转换为值类型的过程。开箱从对象中提取出值类型。开箱是显式的;它需要一个强制转换操作符。

例如:

object y = 10; // 封箱
int x = (int)y; // 开箱

开箱也会发生在将一个object或接口传递给一个期望值类型参数的方法,或者从这样的方法返回一个object或接口时。

开箱也有一些性能影响,因为它涉及到检查类型兼容性和复制数据。它也可能导致运行时错误,如果强制转换是无效的。

动态类型

动态类型是C# 4.0引入的一个新特性,它允许在编译时不指定类型,而在运行时动态绑定类型。使用dynamic关键字可以声明动态变量,编译器会将其视为object或任何接口类型,并生成一些IL代码来调用CLR中的动态语言运行时(DLR)来确定其真实类型和可以执行的操作。

例如:

dynamic x = 10; // 值类型
dynamic y = "Hello"; // 引用类型
x = x + y; // 运行时绑定

动态变量可以保存任何类型的值,包括值类型和引用类型。当动态变量保存值类型的值时,就会发生封箱操作,因为dynamic本质上是object的别名。当从动态变量中提取出值类型时,就会发生开箱操作,因为需要显式地强制转换。

例如:

int x = 10; // 值类型
dynamic y = x; // 封箱
int z = (int)y; // 开箱

动态变量可以提高代码的灵活性和可读性,特别是在处理反射、COM互操作或其他语言之间的交互时。但是,动态类型也有一些缺点,比如:

  • 编译器无法检查动态变量上执行的操作是否有效,只有在运行时才能发现错误。
  • 动态变量无法使用智能感知等IDE功能。
  • 动态变量会增加封箱和开箱操作的次数和开销。
  • 动态变量会降低代码执行速度,因为需要调用DLR来解析运行时绑定。

标签:拆箱,浅谈,C#,object,封箱,开箱,类型,动态
From: https://www.cnblogs.com/netlog/p/17375593.html

相关文章

  • 【Visual Leak Detector】在 VS 高版本中使用 VLD
    说明使用VLD内存泄漏检测工具辅助开发时整理的学习笔记。本篇介绍如何在VS高版本中使用vld2.5.1。同系列文章目录可见《内存泄漏检测工具》目录目录说明1.使用前的准备2.在VS2015及更早版本中使用VLD3.在VS高版本中使用VLD3.1参考资料:在VS2017中使用VLD3.......
  • 【ABC298C】题解
    思路一道很好的复习数据结构的题。对于第\(1\)个问答(既第\(2\)种操作),我用一个小根堆(优先队列,\(\text{priority\_queue}\))来储存第\(i\)个盒子的卡牌。对于第\(2\)个问答(既第\(3\)种操作),我用一个\(\text{set}\)来储存编号为\(i\)个卡牌在哪些盒子里。由于\(\tex......
  • XmlNamespaceManager与XmlDocument.NameTable浅述
    XmlDocumentdoc=newXmlDocument();doc.LoadXml(xml);XmlNamespaceManagernsmgr=newXmlNamespaceManager(doc.NameTable);nsmgr.AddNamespace("ns","http://WebXml.com.cn/");varnodes=doc.SelectNodes("//ns:string",nsmgr);......
  • Error creating bean with name ‘dataSource‘ defined in class path resource解决
    原因是导入了jdbc的依赖,使用@Configuration注解向spring注入了dataSourcebean。但是因为工程中没有关于dataSource相关的配置信息,当spring创建dataSourcebean因缺少相关的信息就会报错。有两个办法:办法1:去除spring-boot-starter-jdbc的依赖或者mybatis的依赖办法2:在Sprin......
  • kettle从入门到精通 第十七课 kettle Transformation executor
    Transformationexecutor步骤是一个流程控件,和映射控件类似却又不一样。1、子转换需要配合使用从结果获取记录和复制记录到结果两个步骤,而子映射需要配合映射输入规范和映射输出规范使用。如下子转换实现的功能是计算x+y的值 2、从结果获取记录1)步骤名称:自定义2)字段:设置从......
  • Nginx(二):实现fastcgi协议代理
    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://xuding.blog.51cto.com/4890434/1743713一、LNMP架构搭建 1.LNMP实现方案     (1)LAMP架构支持三种httpd+php方案            1)......
  • hci
    hci的作用:hci在host和controler都有,其作用是告诉对方怎么解析这个hci数据,如host下发了一个inquiry的命令,controler有hci才能解析出这是一个inquiry命令,而不是将其翻译成其他的命令。commond:host--->controlerevent:         controler--->hostacl:      ......
  • jQuery扩展-noconflict
    Extendsindex.html<!DOCTYPEhtml><html><head><metacharset="utf-8"/><title></title><scriptsrc="../../Scripts/jquery-3.4.1.min.js"></script><scriptsrc="my......
  • The plugin distribution bundles IDE packages 'com.intellij.uiDesigner.core',
    错误描述:TheplugindistributionbundlesIDEpackages'com.intellij.uiDesigner.core','com.intellij.uiDesigner'.BundlingIDEpackagesisconsideredbadpracticeandmayleadtosophisticatedcompatibilityproblems.Considerexcludingthe......
  • [HNCTF 2022 WEEK2]
    easy_unser<?phpinclude'f14g.php';error_reporting(0);highlight_file(__FILE__);classbody{private$want,$todonothing="ican'tgetyouwant,ButyoucantellmebeforeIwakeupandchangemymind"......