C#装箱和拆箱操作实例分析

C#装箱和拆箱操作实例分析

装箱(Boxing)

装箱指的是将值类型转换为对象类型,即将一个值类型的数据放到一个堆分配的对象中。我们知道,值类型的数据是直接存储在内存栈空间中的,而对象类型的数据则是存储在堆空间中的。因此,当我们需要将一个值类型作为对象类型来处理时,就需要进行装箱操作。

下面是一个装箱操作的示例:

int i = 123;
object obj = i;  // 将 int 类型的变量 i 装箱为 object 类型的变量 obj

执行上面的代码后,变量 i 中的值被装箱为 object 类型,并赋值给变量 obj。这样,我们就可以像处理对象类型一样来处理变量 i 了。

需要注意的是,装箱操作会引起内存的分配和数据的复制。如果我们在需要频繁进行装箱和拆箱操作的代码中没有避免,就会大大降低程序的性能。

拆箱(Unboxing)

拆箱指的是将对象类型转换为值类型,即将一个存储在堆中的对象中提取出值类型的数据。当我们需要将一个对象类型转换为值类型时(一般是为了进行数学计算),就需要进行拆箱操作。

下面是一个拆箱操作的示例:

int i = 123;
object obj = i;  // 将 int 类型的变量 i 装箱为 object 类型的变量 obj
int j = (int)obj;  // 将 obj 变量拆箱为 int 类型的变量 j

执行上面的代码后,变量 obj 中存储的 int 类型的数据被拆箱为 int 类型,并赋值给变量 j。

需要注意的是,拆箱操作必须要求装箱操作之前类型相同,否则会引起运行时错误。此外,拆箱操作也会降低程序的性能。

示例说明

示例1:装箱和拆箱操作的性能差异

装箱和拆箱操作带来的性能差异是很明显的。下面是一个示例,演示了在循环中频繁进行装箱和拆箱操作的代码,以及优化后的代码:

// 测试代码1:未优化的装箱和拆箱操作
Stopwatch sw1 = Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
    object obj = i;
    int j = (int)obj;
}
sw1.Stop();
Console.WriteLine("未优化的装箱和拆箱操作时间:{0} 毫秒", sw1.ElapsedMilliseconds);

// 测试代码2:优化后的装箱和拆箱操作
Stopwatch sw2 = Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
    int j = i;
}
sw2.Stop();
Console.WriteLine("优化后的装箱和拆箱操作时间:{0} 毫秒", sw2.ElapsedMilliseconds);

当我们分别执行上面的两段代码时,可以看到性能方面的明显差异:

未优化的装箱和拆箱操作时间:397 毫秒
优化后的装箱和拆箱操作时间:19 毫秒

从上面的结果可以看出,在未优化的代码中涉及到的频繁装箱和拆箱操作明显降低了程序的性能。而优化后的代码不再需要进行装箱和拆箱操作,性能要明显高效得多。

示例2:使用装箱和拆箱操作实现自定义类型转换

通过使用装箱和拆箱操作,我们也可以轻松实现自定义类型之间的转换。下面是一个示例,演示了如何将自定义类型转换为字符串类型:

public struct MyStruct
{
    public int Value1;
    public float Value2;
    public string Value3;

    public override string ToString()
    {
        return string.Format("{{ Value1 = {0}, Value2 = {1}, Value3 = \"{2}\" }}", Value1, Value2, Value3);
    }

    public static implicit operator string(MyStruct value)
    {
        return value.ToString();
    }

    public static explicit operator MyStruct(string value)
    {
        MyStruct result;
        result.Value1 = default(int);
        result.Value2 = default(float);
        result.Value3 = default(string);

        // 省略解析字符串的代码...

        return result;
    }
}

在上面的代码中,我们定义了一个名为 MyStruct 的自定义值类型,并重载了它的 ToString 方法。此外,我们还通过实现 implicit 和 explicit 操作符,指定了如何将 MyStruct 类型转换为 string 类型和如何将 string 类型转换为 MyStruct 类型。

当我们需要将 MyStruct 类型转换为 string 类型时,就可以直接进行装箱操作,例如:

MyStruct myStruct = new MyStruct { Value1 = 123, Value2 = 3.14f, Value3 = "hello" };
string str = myStruct;  // 装箱操作
Console.WriteLine(str);

当我们需要将 string 类型转换为 MyStruct 类型时,就需要进行拆箱操作,例如:

string str = "{ Value1 = 456, Value2 = 6.28, Value3 = \"world\" }";
MyStruct myStruct = (MyStruct)str;  // 拆箱操作
Console.WriteLine(myStruct);

从上面的示例中,我们可以看到,通过实现 implicit 和 explicit 操作符,我们可以在不需要显式调用 ToString 和 Parse 等方法的情况下,实现自定义类型之间的转换,使用起来非常方便。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#装箱和拆箱操作实例分析 - Python技术站

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

相关文章

  • C# 标准事件流实例代码

    首先,我们需要了解什么是 C# 标准事件流。C# 标准事件流是一种事件源和事件处理程序之间的机制,允许一个或多个事件处理程序能够对事件进行处理。 下面是一个 C# 标准事件流实例代码的完整攻略: 1. 定义事件和事件处理程序 首先,我们需要定义一个事件和至少一个事件处理程序。在这个例子中,我们定义了一个名为 ButtonClick 的事件和一个名为 OnBu…

    C# 2023年6月7日
    00
  • C#使用CancellationTokenSource 取消 Task的方法

    下面是详细讲解C#使用CancellationTokenSource取消Task的方法的完整攻略: 什么是CancellationTokenSource CancellationTokenSource是一个C#中的类,它用于取消一个或多个CancellationToken实例。可以将其视为控制任务执行过程的信号灯。当在CancellationTokenSou…

    C# 2023年6月6日
    00
  • 比较简单的将数据信息导入wrod文档方案(C# for word)

    完整攻略如下: 标题 比较简单的将数据信息导入Word文档方案(C#forword) 准备工作 安装Microsoft.Office.Interop.Word组件 导入数据信息的步骤 创建Word文档 使用Microsoft.Office.Interop.Word组件创建Word文档,可以使用如下代码: “`csharp // 创建Application对…

    C# 2023年5月15日
    00
  • C#中数组、ArrayList、List、Dictionary的用法与区别浅析(存取数据)

    下面是关于C#中数组、ArrayList、List、Dictionary的用法与区别浅析(存取数据)的完整攻略。 数组 定义 数组是一种数据结构,可以在单个变量下存储多个值。在C#中,数组是由相同类型的元素组成的集合。可以使用数组来存储一个固定数量的元素,这些元素在创建数组时就已被确定。 用法 创建数组 在C#中创建数组,需要指定数组的长度,然后使用关键字n…

    C# 2023年5月31日
    00
  • 详解C#实例化对象的三种方式及性能对比

    详解C#实例化对象的三种方式及性能对比 在C#中,创建一个对象有多种方法,每种方法都有自己的优势和适用场景。本文将详解C#实例化对象的三种方式,并进行性能对比。 1. 直接实例化 这是最常见的创建对象的方式,使用new关键字直接创建一个对象。 ClassA a = new ClassA(); 由于直接实例化创建对象的时候不需调用构造器,因此速度最快,节省了构…

    C# 2023年6月1日
    00
  • CommunityToolkit.Mvvm8.1 消息通知(4)

    本系列文章导航 https://www.cnblogs.com/aierong/p/17300066.html https://github.com/aierong/WpfDemo (自我Demo地址)   希望提到的知识对您有所提示,同时欢迎交流和指正 作者:aierong出处:https://www.cnblogs.com/aierong   说明 为了…

    C# 2023年4月22日
    00
  • 如何在UpdatePanel中调用JS客户端脚本

    在 ASP.NET 中,可以使用 UpdatePanel 控件来实现局部异步刷新页面的效果。但是,默认情况下,UpdatePanel 不支持调用客户端JS脚本。本文就讲解如何在 UpdatePanel 中调用JS客户端脚本,通过两个示例帮助读者更好地理解。 方法一:使用ScriptManager类的RegisterStartupScript方法 在 Upda…

    C# 2023年6月6日
    00
  • C#基于百度AI实现机器翻译功能

    下面是“C#基于百度AI实现机器翻译功能”完整攻略的详细讲解。 1. 准备工作 在开始实现机器翻译功能之前,我们需要先准备好所需要的资源和工具: 1.1 安装百度AI SDK 访问百度AI开放平台并注册账号,然后可以在控制台获取到 api_key 和 secret_key。 百度AI SDK提供了各种AI相关的服务,我们需要安装其中的机器翻译SDK,可以通过…

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