”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > C#拳击和拆箱:何时以及为什么需要它们?

C#拳击和拆箱:何时以及为什么需要它们?

发布于2025-01-29
浏览:618

C# Boxing and Unboxing: When and Why Do We Need Them?

C#中的装箱和拆箱:原因和应用场景

引言

在C#中,装箱和拆箱是协调值类型和引用类型不同行为的必要机制。然而,它们的用途和用例可能会让程序员感到困惑。本指南阐明了为什么这些概念至关重要,并提供了其实际应用的示例。

装箱和拆箱的重要性

装箱和拆箱允许C#维护一个统一的类型系统,使值类型和引用类型能够一致地交互和处理。值类型(例如short和int)将其数据直接存储在变量中。相反,引用类型引用位于内存中其他位置的底层对象。

为了促进这些不同数据结构之间的无缝交互,装箱创建一个包装对象,包含值类型的数据,使其可以像引用类型一样对待。这使得可以轻松地在专为引用类型设计的的数据结构中存储和操作值类型。

装箱和拆箱的应用场景

装箱的一个经典用例是使用遗留集合,这些集合只接受对象。这些集合需要装箱才能存储值类型,如ArrayList示例所示:

short s = 25;
object objshort = s;  // 装箱

在现代泛型时代,装箱的需求减少了。但是,它在特定场景中仍然至关重要:

  • 隐式转换: 装箱处理值类型和引用类型之间的隐式转换,例如:
double e = 2.718281828459045;
int ee = (int)e;  // 从double到int的隐式转换(需要装箱)
  • 相等性比较: 引用类型默认比较它们的引用。要比较底层值,需要拆箱和显式转换:
double e = 2.718281828459045;
object o = e;  // 装箱
int ee = (int)(double)o;  // 拆箱和显式转换
  • 值传递与引用传递: 装箱和拆箱影响值类型传递给方法的方式。如果在将值类型作为参数传递之前将其装箱,则在方法内对参数所做的任何修改都不会影响原始值。

需要注意的细节

  • 引用相等与值相等: 引用类型使用引用相等进行 == 比较,它检查引用是否相同,而不是底层值。这可能导致意想不到的结果:
double e = 2.718281828459045;
object o1 = e;
object o2 = e;
Console.WriteLine(o1 == o2);  // False
  • 复制行为: 装箱结构体(值类型)时,会创建一个副本。相反,装箱类(引用类型)时,会创建一个对原始对象的引用。这种行为上的差异会影响对装箱值的运算结果:
[struct|class] Point { ... }
Point p = new Point(1, 1);
object o = p;
p.x = 2;
Console.WriteLine(((Point)o).x);  // 输出:1(如果为结构体)/ 2(如果为类)
最新教程 更多>
  • JavaScript计算两个日期之间天数的方法
    JavaScript计算两个日期之间天数的方法
    How to Calculate the Difference Between Dates in JavascriptAs you attempt to determine the difference between two dates in Javascript, consider this s...
    编程 发布于2025-04-23
  • Python中嵌套函数与闭包的区别是什么
    Python中嵌套函数与闭包的区别是什么
    嵌套函数与python 在python中的嵌套函数不被考虑闭合,因为它们不符合以下要求:不访问局部范围scliables to incling scliables在封装范围外执行范围的局部范围。 make_printer(msg): DEF打印机(): 打印(味精) ...
    编程 发布于2025-04-23
  • 如何从2D数组中提取元素?使用另一数组的索引
    如何从2D数组中提取元素?使用另一数组的索引
    Using NumPy Array as Indices for the 2nd Dimension of Another ArrayTo extract specific elements from a 2D array based on indices provided by a second ...
    编程 发布于2025-04-23
  • 如何在Java字符串中有效替换多个子字符串?
    如何在Java字符串中有效替换多个子字符串?
    在java 中有效地替换多个substring,需要在需要替换一个字符串中的多个substring的情况下,很容易求助于重复应用字符串的刺激力量。 However, this can be inefficient for large strings or when working with nu...
    编程 发布于2025-04-23
  • 如何干净地删除匿名JavaScript事件处理程序?
    如何干净地删除匿名JavaScript事件处理程序?
    删除匿名事件侦听器将匿名事件侦听器添加到元素中会提供灵活性和简单性,但是当要删除它们时,可以构成挑战,而无需替换元素本身就可以替换一个问题。 element? element.addeventlistener(event,function(){/在这里工作/},false); 要解决此问题,请考虑...
    编程 发布于2025-04-23
  • 如何在鼠标单击时编程选择DIV中的所有文本?
    如何在鼠标单击时编程选择DIV中的所有文本?
    在鼠标上选择div文本单击带有文本内容,用户如何使用单个鼠标单击单击div中的整个文本?这允许用户轻松拖放所选的文本或直接复制它。 在单个鼠标上单击的div元素中选择文本,您可以使用以下Javascript函数: function selecttext(canduterid){ if(do...
    编程 发布于2025-04-23
  • Async Void vs. Async Task在ASP.NET中:为什么Async Void方法有时会抛出异常?
    Async Void vs. Async Task在ASP.NET中:为什么Async Void方法有时会抛出异常?
    在ASP.NET async void void async void void void void void的设计无需返回asynchroncon而无需返回任务对象。他们在执行过程中增加未偿还操作的计数,并在完成后减少。在某些情况下,这种行为可能是有益的,例如未期望或明确预期操作结果的火灾和...
    编程 发布于2025-04-23
  • 如何从PHP中的Unicode字符串中有效地产生对URL友好的sl。
    如何从PHP中的Unicode字符串中有效地产生对URL友好的sl。
    为有效的slug生成首先,该函数用指定的分隔符替换所有非字母或数字字符。此步骤可确保slug遵守URL惯例。随后,它采用ICONV函数将文本简化为us-ascii兼容格式,从而允许更广泛的字符集合兼容性。接下来,该函数使用正则表达式删除了不需要的字符,例如特殊字符和空格。此步骤可确保slug仅包含...
    编程 发布于2025-04-23
  • 如何修复\“常规错误:2006 MySQL Server在插入数据时已经消失\”?
    如何修复\“常规错误:2006 MySQL Server在插入数据时已经消失\”?
    How to Resolve "General error: 2006 MySQL server has gone away" While Inserting RecordsIntroduction:Inserting data into a MySQL database can...
    编程 发布于2025-04-23
  • C++20 Consteval函数中模板参数能否依赖于函数参数?
    C++20 Consteval函数中模板参数能否依赖于函数参数?
    [ consteval函数和模板参数依赖于函数参数在C 17中,模板参数不能依赖一个函数参数,因为编译器仍然需要对非contexexpr futcoriations contim at contexpr function进行评估。 compile time。 C 20引入恒定函数,必须在编译时进行...
    编程 发布于2025-04-23
  • 解决MySQL错误1153:数据包超出'max_allowed_packet'限制
    解决MySQL错误1153:数据包超出'max_allowed_packet'限制
    mysql错误1153:故障排除比“ max_allowed_pa​​cket” bytes 更大的数据包,用于面对阴谋mysql错误1153,同时导入数据capase doft a Database dust?让我们深入研究罪魁祸首并探索解决方案以纠正此问题。理解错误此错误表明在导入过程中接...
    编程 发布于2025-04-23
  • JavaScript中如何动态访问全局变量?
    JavaScript中如何动态访问全局变量?
    在JavaScript 一种方法是使用窗口对象存储和检索变量。通过引用全局范围,可以使用其名称动态访问变量。 //一个脚本 var somevarname_10 = 20; //另一个脚本 window.all_vars = {}; window.all_vars ['somevarnam...
    编程 发布于2025-04-23
  • 如何从Python中的字符串中删除表情符号:固定常见错误的初学者指南?
    如何从Python中的字符串中删除表情符号:固定常见错误的初学者指南?
    从python import codecs import codecs import codecs 导入 text = codecs.decode('这狗\ u0001f602'.encode('utf-8'),'utf-8') 印刷(文字)#带有...
    编程 发布于2025-04-23
  • 如何克服PHP的功能重新定义限制?
    如何克服PHP的功能重新定义限制?
    克服PHP的函数重新定义限制在PHP中,多次定义一个相同名称的函数是一个no-no。尝试这样做,如提供的代码段所示,将导致可怕的“不能重新列出”错误。 但是,PHP工具腰带中有一个隐藏的宝石:runkit扩展。它使您能够灵活地重新定义函数。 runkit_function_renction_re...
    编程 发布于2025-04-23
  • C++中如何将独占指针作为函数或构造函数参数传递?
    C++中如何将独占指针作为函数或构造函数参数传递?
    在构造函数和函数中将唯一的指数管理为参数 unique pointers( unique_ptr [2启示。通过值: base(std :: simelor_ptr n) :next(std :: move(n)){} 此方法将唯一指针的所有权转移到函数/对象。指针的内容被移至功能中,在操作...
    编程 发布于2025-04-23

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3