.NET 中的装箱与拆箱实现过程

.NET 中的装箱与拆箱实现过程

什么是装箱和拆箱?

在 .NET 中,将值类型变量转换为引用类型变量的过程就称为 装箱(boxing),而将引用类型变量转换为值类型变量的过程则称为 拆箱(unboxing)

装箱和拆箱在 .NET 中非常常见,比如我们经常使用 List<T>Dictionary<TKey, TValue> 等集合类型,它们所有元素都是对象。而值类型变量本身并不是对象,它们存储在栈中,而对象则存储在堆中。当我们需要使用值类型变量时,需要将其转换为对象,这就是装箱。而从对象中取出值类型变量,将其放回栈中,就是拆箱。

装箱的实现过程

装箱的实现过程主要分为以下两步:

  1. 在堆中分配内存空间,用来存储值类型变量的值。
  2. 创建引用类型变量,将堆中的内存空间的地址赋值给该变量,以便引用该堆中的值类型变量。

以下是一个示例:

int i = 42;        // 定义一个值类型变量 i,其值为 42
object obj = i;    // 装箱:将值类型变量 i 转换为一个 object 类型的引用类型变量 obj

在上面的代码中,对象 obj 在堆中分配了一段内存空间用于存储变量 i 的值,然后将该对象的地址赋值给 obj,即完成了装箱的过程。

拆箱的实现过程

拆箱的实现过程主要分为以下两步:

  1. 检查引用类型变量是否为装箱的类型。
  2. 从对象中取出值类型变量的值,将其放入栈中。

以下是一个示例:

int i = 0;         // 定义一个值类型变量 i,其值为 0
object obj = 42;   // 定义一个 object 类型的引用类型变量 obj,并将其赋值为 42

if (obj is int)    // 检查 obj 是否为 int 类型
{
    i = (int)obj;  // 拆箱:将 obj 转换为 int 类型的值类型变量,并将其赋值给 i
}

在上面的代码中,使用关键字 is 检查 obj 是否为 int 类型,如果是,就将 obj 转换为 int 类型,并将其赋值给值类型变量 i,即完成了拆箱的过程。

示例一:装箱和拆箱的影响

我们来看一个示例,了解装箱和拆箱的一些影响。假设有以下代码:

int i = 42;              // 定义一个值类型变量 i,其值为 42
object obj1 = (object)i; // 将 i 装箱,并将其赋值给 obj1

// 拆箱之前
Console.WriteLine("i = " + i);         // 输出:i = 42
Console.WriteLine("obj1 = " + obj1);   // 输出:obj1 = 42

// 拆箱
int j = (int)obj1;        // 将 obj1 拆箱,并将其赋值给 j

// 拆箱之后
Console.WriteLine("i = " + i);         // 输出:i = 42
Console.WriteLine("obj1 = " + obj1);   // 输出:obj1 = 42
Console.WriteLine("j = " + j);         // 输出:j = 42

i = 100;                  // 修改 i 的值

// 修改 i 的值之后
Console.WriteLine("i = " + i);         // 输出:i = 100
Console.WriteLine("obj1 = " + obj1);   // 输出:obj1 = 42
Console.WriteLine("j = " + j);         // 输出:j = 42

在上面的代码中,首先将变量 i 装箱为 obj1,然后将其拆箱为变量 j。我们发现,修改 i 的值后,obj1 的值并没有变化,而且修改 i 的值也不会影响变量 j 的值。这是因为装箱实际上创建了一个新的对象,而拆箱仅仅将该对象中的值复制到一个新的值类型变量中。

示例二:装箱和拆箱的性能影响

装箱和拆箱操作会带来额外的开销,因为它们需要在堆和栈之间进行数据的复制,这会增加内存的使用和垃圾回收的负担,并且会降低程序的性能。下面是一个示例,演示了装箱和拆箱的性能影响:

int i = 0;
object obj = 0;
Stopwatch watch = new Stopwatch();

// 执行装箱操作 10 万次,并计时
watch.Start();
for (int j = 0; j < 100000; j++)
{
    obj = i;    // 装箱
}
watch.Stop();
Console.WriteLine("装箱操作耗时:" + watch.ElapsedTicks + " ticks");

// 执行拆箱操作 10 万次,并计时
watch.Restart();
for (int j = 0; j < 100000; j++)
{
    i = (int)obj;    // 拆箱
}
watch.Stop();
Console.WriteLine("拆箱操作耗时:" + watch.ElapsedTicks + " ticks");

在上面的代码中,我们使用了一个计时器来统计执行装箱和拆箱操作的时间。结果可能因机器而异,但通常拆箱耗时要比装箱多得多。这也提醒我们,在某些情况下要尽力避免使用装箱和拆箱操作,以提高程序的性能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:.NET 中的装箱与拆箱实现过程 - Python技术站

(0)
上一篇 2023年6月3日
下一篇 2023年6月3日

相关文章

  • C#编写的Base64加密和解密类

    基于C#语言的编写Base64加密和解密类可遵循以下步骤: 第一步:引用命名空间 using System; using System.Text; 第二步:定义加密和解密方法 public static string Base64Encode(string str) { byte[] bytes = Encoding.UTF8.GetBytes(str); …

    C# 2023年6月7日
    00
  • C# Clear():从集合中移除所有元素

    C#中的Clear()方法是一个实例方法,通常用于清空某些数据结构中的元素,例如字符串、数组、集合等。以下是C# Clear()的完整攻略,包括用法、示例和注意事项。 用法 Clear()方法是通过.运算符调用的实例方法,该方法不接受参数,返回值为void类型。可以使用Clear()方法来清空String、StringBuilder、List、Diction…

    C# 2023年4月19日
    00
  • .NET Core部署到linux(CentOS)最全解决方案,入魔篇(使用Docker+Jenkins实现持续集成、自动化部署)

    通过前面三篇: .NET Core部署到linux(CentOS)最全解决方案,常规篇 .NET Core部署到linux(CentOS)最全解决方案,进阶篇(Supervisor+Nginx) .NET Core部署到linux(CentOS)最全解决方案,高阶篇(Docker+Nginx 或 Jexus) 通过前面三篇文章的介绍,我们已经对.net co…

    C# 2023年5月7日
    00
  • C#关键字之覆写overwrite介绍

    C#关键字之覆写(Overwrite)介绍 在C#中,通常情况下,子类从父类继承了一些属性和功能,如果子类想要修改这些属性或功能,可以使用覆写(Overwrite)的方式。 覆写的作用 通过覆写,子类可以重写父类的属性和方法,从而符合自己的需要。这种方法可以覆盖父类的行为或属性,使得子类对象在覆盖的行为或属性上拥有更多控制力。覆写的常见应用是子类修改父类特定…

    C# 2023年6月7日
    00
  • c# 剔除sql语句’尾巴’的五种方法

    接下来我将为大家详细介绍“C#剔除SQL语句‘尾巴’的五种方法”: 一、问题描述 有时候在编写C#程序时,我们需要动态生成SQL语句。但是在动态生成SQL语句中,由于字符串拼接不当可能会导致语句的末尾出现多余的“AND”、“OR”等关键字,这就需要我们对字符串进行处理,去掉这些多余的关键字,以保证SQL语句的正确性。 下面将介绍五种方法来解决这个问题。 二、…

    C# 2023年5月15日
    00
  • C#实现串口调试工具

    下面是关于C#实现串口调试工具的完整攻略: 1. 前期准备 在使用C#来实现串口调试工具之前,首先要准备好相关的环境和工具。具体的步骤如下: 安装Visual Studio开发工具,选择适合自己的版本。 新建一个项目,选择“Windows窗体应用程序”。 在项目中添加“串口”控件。 2. 界面设计 接下来要进行的步骤是对调试工具的界面进行设计。通过界面设计,…

    C# 2023年6月6日
    00
  • ASP.NET CORE读取json格式配置文件

    ASP.NET Core 读取 JSON 格式配置文件的流程: 在 appsettings.json 文件中定义所需的配置项。 在 Program.cs 文件中使用 CreateDefaultBuilder(args) 方法创建 IHostBuilder 对象,并在 ConfigureAppConfiguration(…) 方法中添加读取配置文件的功能。…

    C# 2023年6月3日
    00
  • Winform控件Picture实现图片拖拽显示效果

    详细讲解Winform控件Picture实现图片拖拽显示效果的完整攻略。 1. 实现效果 我们将实现一个Winform窗体应用程序,其界面上有一个Picture控件,用户可以通过拖拽图片到Picture控件上实现图片显示。 2. 实现步骤 下面是我们实现此功能的步骤: 2.1 在窗体上添加Picture控件 在Visual Studio中创建一个Winfor…

    C# 2023年6月2日
    00
合作推广
合作推广
分享本页
返回顶部