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#元组类型ValueTuple用法详解

    C#元组类型ValueTuple用法详解 简介 元组类型是C#7.0之后加入的新特性,提供了一种简单方便的方式来存储和传递多个值。元组类型有两种:ValueTuple和Tuple。 本篇攻略将详细讲解ValueTuple类型的用法。 ValueTuple类型的定义 ValueTuple是一个泛型结构体(struct),它所定义的元组类型可以存储1~8个元素,…

    C# 2023年6月7日
    00
  • C# Path.GetFullPath – 获取路径的完整路径

    Path.GetFullPath 方法是 .NET 中用于获取给定路径的完整路径的静态方法。它将解析任何相对路径,并将其转换为绝对路径。 使用该方法时,可以传递一个字符串类型的路径作为参数,它将返回一个字符串类型的绝对路径。 例如,在 Windows 操作系统下,将字符串 “myFolder/myFile.txt” 作为参数传递给 Path.GetFullP…

    C# 2023年4月19日
    00
  • jsp和asp.net共享session值示例代码

    当用户使用JSP应用程序访问ASP.NET应用程序时,需要在这两个应用程序之间共享sessions,这可以用以下两种方法实现:使用相同的session ID,使用数据库来持久化sessions。 下面是使用相同的session ID来共享跨平台sessions的示例代码: 首先,要在相应的服务器端设置session ID的cookie为Java Servle…

    C# 2023年5月31日
    00
  • 图文介绍c#封装方法

    图文介绍c#封装方法 在c#编程中,封装是面向对象编程中一个非常重要的概念,它允许我们将数据和方法包装到一起,并限制对其的访问。在本文中,我们将介绍如何在c#中封装方法,并提供两个示例以说明如何使用封装方法。 什么是封装 封装指的是将数据和方法包装到一起,以隐藏其具体实现细节,并限制对其的直接访问。在c#中,我们使用访问修饰符来控制对数据和方法的访问级别。包…

    C# 2023年6月3日
    00
  • C#使用读写锁解决多线程并发问题

    下面就是C#使用读写锁解决多线程并发问题的完整攻略。 什么是读写锁 读写锁是一种并发控制机制,它允许多个线程同时读取共享的数据,但在写入数据时需要互斥访问,即写者独占。 为什么需要读写锁 在多线程程序中,当多个线程同时读取共享数据时,如果没有对其进行保护,容易出现数据不一致的情况,也可能会降低程序性能。而使用读写锁则可以解决这个问题,提高程序性能。 C#中的…

    C# 2023年5月15日
    00
  • ASP.NET MVC生成静态页面的方法

    生成静态页面是网站优化中常用的手段之一,能够有效提高网站的访问速度和用户体验。在ASP.NET MVC中,我们可以使用以下两种方法来生成静态页面。 方法一:使用HtmlHelper的Action方法 步骤一:添加路由规则 首先,在RouteConfig.cs文件中,添加一个路由规则,用于匹配需要生成静态页面的 action。 routes.MapRoute(…

    C# 2023年5月31日
    00
  • 详解C# 网络编程系列:实现类似QQ的即时通信程序

    详解C#网络编程系列:实现类似QQ的即时通信程序 简介 本文将详细讲解如何使用C#网络编程实现类似QQ的即时通信程序,该程序基于TCP协议,使用Socket实现客户端与服务端的通信,涵盖了详细的代码实现和功能介绍。 实现步骤 设计即时通信协议。 实现服务端程序,包括监听和处理客户端请求。 实现客户端程序,包括连接和向服务端发送请求。 实现消息发送和接收功能。…

    C# 2023年5月15日
    00
  • .NET Core系列之MemoryCache 缓存选项

    .NET Core系列之MemoryCache 缓存选项 在.NET Core中,MemoryCache是一种内存缓存,可用于缓存应用程序中的数据。MemoryCache提供了多种缓存选项,可以根据应用程序的需求进行配置。本攻略将介绍MemoryCache的缓存选项,包括缓存过期、缓存优先级、缓存回调等,并提供两个示例说明。 缓存过期 在MemoryCach…

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