c#基础系列之值类型和引用类型的深入理解

C#基础系列之值类型和引用类型的深入理解

值类型和引用类型

C#中的变量可以分为值类型和引用类型两种。所谓值类型,就是它们在内存中直接存储它们的值,而引用类型则存储对象在内存中的地址。常见的值类型包括整型、浮点型、布尔型和枚举类型,而常见的引用类型包括类、接口、数组和委托等。

值类型使用堆栈空间存储,可以直接访问,速度较快,但是数据量较小,一般在32位系统中为4字节,在64位系统中为8字节。而引用类型的大小是由它们指向的对象所决定的,通常要进行堆内存的分配和释放,速度较慢。

值类型的特点

  1. 存储在堆栈中;
  2. 直接包含变量的值,速度快;
  3. 分配和销毁速度快;
  4. 值类型不能为 null;
  5. 值类型实例之间的比较,是比较它们的值是否相等;

下面以整型变量为例展示值类型:

int x = 10; // x 是值类型
int y = x;
y = 20; // x 不会改变

同样是整型,x和y是两个不同的变量,它们在内存中分别存储它们的值,x=10,y=20。将y赋值给x之后,x和y的值都是10。当我们将y的值修改为20时,x的值不会随之改变。

引用类型的特点

  1. 存储在堆中;
  2. 存储的是一个指向对象的地址;
  3. 分配和销毁需要额外的处理;
  4. 引用类型可以为 null;
  5. 引用类型实例之间的比较,是比较它们的引用是否相等;

下面以类为例展示引用类型:

class Person {
    public string Name { get; set; }
}

Person p1 = new Person() { Name = "Jay" }; // p1 是引用类型
Person p2 = p1; // p1 和 p2 引用同一个对象
p2.Name = "Bob";
Console.WriteLine(p1.Name); // 输出 "Bob"

在这个例子中,我们使用了一个Person类,它存储了一个人的姓名。首先,我们创建了一个名为p1的Person对象,并设置了它的Name属性为"Jay"。然后,我们将p1赋值给了p2,这样p1和p2都指向同一个Person对象。当我们修改p2的Name属性时,p1的Name属性也会发生改变,这是因为它们引用同一个对象。

总结

值类型和引用类型有各自的特点。在开发过程中,我们需要根据实际情况使用不同的类型。通常情况下,如果我们需要存储一个简单的数值类型或者枚举类型等,那么我们可以使用值类型,如果我们需要使用一个较为复杂的对象,那么我们可以使用引用类型。

示例1:值类型

enum Gender { Male, Female }
struct Person {
    public string Name { get; set; }
    public Gender Gender { get; set; }
}
Person p1 = new Person { Name = "Tom", Gender = Gender.Male };
Person p2 = p1;
p2.Name = "Jerry";
Console.WriteLine(p1.Name); // 输出 "Tom"

在这个示例中,我们定义了一个结构体Person,它包含一个Name属性和一个Gender属性。我们创建了一个Person对象p1,并设置它的Name为"Tom",然后将其赋值给p2。接着,我们修改了p2的Name属性为"Jerry",但p1的Name属性却没有发生改变,这是因为Person是一个结构体,它是一个值类型。

示例2:引用类型

class Cat {
    public string Name { get; set; }
    public void Speak() {
        Console.WriteLine($"{Name}说:喵~");
    }
}
Cat c1 = new Cat { Name = "Tom" };
Cat c2 = c1;
c2.Name = "Jerry";
c1.Speak(); // 输出 "Jerry说:喵~"

在这个示例中,我们定义了一个Cat类,它包含一个Name属性和一个Speak方法。首先,我们创建了一个Cat对象c1,并设置它的Name为"Tom",然后将其赋值给c2。接着,我们修改了c2的Name属性为"Jerry",并调用c1的Speak方法,发现输出的是"Jerry说:喵~",这是因为Cat是一个类,它是一个引用类型。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:c#基础系列之值类型和引用类型的深入理解 - Python技术站

(0)
上一篇 2023年5月15日
下一篇 2023年5月15日

相关文章

  • C#利用Windows自带gdi32.dll实现抓取屏幕功能实例

    下面是C#利用Windows自带gdi32.dll实现抓取屏幕功能的完整攻略: 第一步:导入gdi32.dll库 要使用gdi32.dll中的函数,我们需要手动导入该库,首先需要在原生方法前加入[DllImport(“gdi32.dll”)],以便让.NET框架能够找到该库。然后需要在代码开头添加命名空间:using System.Runtime.Inter…

    C# 2023年5月31日
    00
  • C# DatagridView常用操作汇总

    C# DataGridView常用操作汇总 前言 在C# Winform应用程序开发中,DataGridView是一个非常实用的控件,它可以用来显示和编辑数据,而且比起ListView控件来说更加灵活,功能更加丰富。在本攻略中,我们会介绍DataGridView控件的常用操作,包括如何绑定数据源、如何设置单元格样式、如何实现排序过滤和单元格合并等。 绑定数据…

    C# 2023年5月15日
    00
  • C# 设计模式系列教程-外观模式

    下面是基于 Markdown 格式的完整攻略: C# 设计模式系列教程-外观模式 什么是外观模式 外观模式(Facade Pattern)是一种结构型设计模式,它提供了一个简单的界面,隐藏了复杂的系统,并且将系统中的多个组件打包成一个单一的组件,从而使得系统更加容易使用和更加易于维护。 外观模式解决了什么问题 在一个复杂的系统中,有时候我们不想暴露系统的所有…

    C# 2023年6月7日
    00
  • 浅谈ASP.NET Core静态文件处理源码探究

    在ASP.NET Core中,静态文件处理是一个非常重要的功能。本攻略将深入探讨ASP.NET Core静态文件处理的源码实现,并提供两个示例说明。 1. 静态文件处理的基本原理 在ASP.NET Core中,静态文件处理的基本原理是将请求映射到文件系统中的静态文件。当请求到达应用程序时,ASP.NET Core会检查请求路径是否匹配静态文件的路径。如果匹配…

    C# 2023年5月17日
    00
  • C#用timer实现背单词小程序

    下面是详细的攻略: 1. 准备工作 在开始编写C#背单词小程序之前,需要准备以下工作: 安装Visual Studio开发环境 确认安装了.NET Framework 4.5或以上版本 准备一个背单词的数据源 2. 创建Windows窗体应用 首先,我们需要在Visual Studio中创建一个Windows窗体应用程序,用来作为程序的容器。 3. 设计程序…

    C# 2023年6月1日
    00
  • CPF 使用C#的Native AOT 发布程序的详细过程

    下面我将为你详细讲解如何使用C#的Native AOT发布程序。我们可以分为以下几个步骤来完成该过程: 安装必要的工具和组件 编写C#代码,确保它可以编译 使用AOT(Ahead Of Time)编译器生成本机代码 打包本机代码和必要的依赖文件 测试和发布应用程序 接下来,我将提交示例,以更好地演示这个过程。 步骤一:安装必要的工具和组件 首先,我们需要在开…

    C# 2023年5月15日
    00
  • ASP.NET Core MVC 从入门到精通之初窥门径

    随着技术的发展,ASP.NET Core MVC也推出了好长时间,经过不断的版本更新迭代,已经越来越完善,本系列文章主要讲解ASP.NET Core MVC开发B/S系统过程中所涉及到的相关内容,适用于初学者,在校毕业生,或其他想从事ASP.NET Core MVC 系统开发的人员,仅供学习分享使用。   什么是MVC?   MVC是一种架构模式,也是一种设…

    C# 2023年4月18日
    00
  • .net后台代码调用前台JS的两种方式

    你可以按照以下步骤来进行。 步骤一:引入前端JS文件 在实现后台调用前台JS的功能之前,首先需要在HTML页面引入JS文件。我们可以使用以下代码引入JS文件: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo…

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