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# yield关键字详解

    C#yield关键字详解 yield 是 C# 中的一个关键字,它可以用来创建迭代器。一个包括 yield 语句的方法或者运算符,被称之为迭代器方法或者迭代器块。 在一个迭代器方法中,通过 yield return 语句向调用者返回一个序列中的下一个元素。每次调用 iterator 方法时,通过 yield return 返回的元素会被记录下来,并暂停方法的…

    C# 2023年5月15日
    00
  • C#关机小程序源码

    对于“C#关机小程序源码”的完整攻略,我将从以下几个方面进行详细讲解: 实现功能及设计思路 编写代码及说明 示例说明 1. 实现功能及设计思路 本小程序的主要功能为实现计算机关机,设计思路为利用C#的系统调用函数,调用Windows的API函数实现计算机的关机操作。 具体实现步骤如下: 创建一个Windows窗口应用程序 在程序中添加一个按钮控件,用于触发计…

    C# 2023年6月1日
    00
  • C#代码实现对AES加密解密

    下面是C#代码实现对AES加密解密的完整攻略。 1. 引入所需的命名空间 在C#代码实现对AES加密解密之前,我们需要先引入所需的命名空间。对于AES加密解密,我们需要引入System.Security.Cryptography命名空间。 using System.Security.Cryptography; 2. 生成密钥和向量 在进行AES加密解密之前,…

    C# 2023年6月8日
    00
  • ASP.NET MVC4 HtmlHelper扩展类,实现分页功能

    ASP.NET MVC4是一种Web应用程序框架,它提供了一种模型-视图-控制器(MVC)的架构模式,用于构建可扩展的Web应用程序。在ASP.NET MVC4中,HtmlHelper是一个非常有用的类,它提供了许多有用的方法,例如生成HTML标记、表单、分页等。在本文中,我们将介绍如何使用HtmlHelper扩展类来实现分页功能。 步骤一:创建HtmlHe…

    C# 2023年5月17日
    00
  • BootStrap mvcpager分页样式(get请求,刷新页面)

    下面是详细讲解”BootStrap mvcpager分页样式(get请求,刷新页面)”的攻略。 什么是Bootstrap MvcPager? Bootstrap MvcPager是一个基于ASP.NET MVC的分页控件,它支持Bootstrap 3和4版本,并且提供了多种自定义风格。利用它可以方便地实现Bootstrap风格的分页效果。 实现Bootstr…

    C# 2023年5月31日
    00
  • 手把手教你如何基于C#制作一个网址检测工具

    手把手教你基于C#制作一个网址检测工具 简介 网址检测工具是一种用来检测网址是否可用的工具,可以帮助用户快速定位网站故障原因,提高用户的使用体验。该教程框架基于C#语言,本文将详细阐述如何基于C#制作一个网址检测工具。 准备工作 在开始之前,请先安装好 .NET环境,并下载安装 Visual Studio。 实现步骤 1. 创建项目 在 Visual Stu…

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

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

    C# 2023年6月6日
    00
  • 灵活使用asp.net中的gridview控件

    使用ASP.NET中的GridView控件可以快速实现数据的呈现和管理。下面是灵活使用GridView控件的攻略: 1.绑定数据源 GridView控件的数据源可以是DataTable、DataSet、Array等多种类型的对象。以下是以DataTable作为数据源的示例: protected void Page_Load(object sender, Ev…

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