C# 中值类型和引用类型的解释和对比

2025年3月17日 | 阅读 8 分钟

在 C# 中,值类型引用类型是基本的数据类型,它们各自具有不同的行为和用途。这些类型决定了变量在内存中的存储位置以及赋值时的行为。在本文中,我们将讨论 C# 中值类型和引用类型之间的区别。但在讨论它们之间的区别之前,我们必须了解 C# 中的值类型和引用类型。

什么是值类型?

值类型用于在堆栈上存储内存中的数据。当一个特定的值被赋给变量,或者一个值作为参数传递给它时,会创建一个该值的副本。这种值类型继承自System.ValueType。在这里,每个变量都有自己的数据副本。值类型直接包含值。

值类型又分为两种:预定义内置值类型和用户定义值类型。预定义类型存在于 C# 编程语言中。它们是数值、字符和十进制类型。

数值类型包括整型和浮点型。整型又分为 short、int 和 long。字符类型用于在堆栈上存储单个字符,有时也用于存储布尔类型。

示例

让我们举一个例子来说明 C# 中的预定义值类型。

输出

Explain and contrast value types and reference types in C#

用户定义值类型

用户定义类型是由用户为特定需求创建的值类型。重要的用户定义类型是结构体(struct)和枚举(enum)。'struct' 关键字用于创建结构体。'enum' 关键字用于创建枚举,结构体类似于类。结构体包含数据成员和成员函数,但它们比类更轻量。枚举由一组命名常量组成。它使代码或程序更具可读性和可维护性。

示例 2

让我们再举一个例子来说明 C# 中的结构体。

输出

Explain and contrast value types and reference types in C#

示例 3

让我们再举一个例子来说明 C# 中的枚举

输出

Explain and contrast value types and reference types in C#

什么是引用类型?

引用类型用于在托管堆上存储数据。引用类型携带指向实际数据存储所在内存位置的指针。这种引用类型继承自System.Object。当我们把一个引用类型变量赋给另一个变量时,它会创建一个指向相同数据的新的指针,而不是创建一个新的数据副本。堆上会有许多指针或引用指向同一个对象。

它们也分为两种:内置引用类型或预定义引用类型和用户定义引用类型。

内置引用类型

内置引用类型又有不同的类型。其中一些是数组、字符串、对象、字典、线程、流等。众所周知,数组代表同一种数据类型的元素集合。字符串是 C# 中不可变的字符序列。对象是 C# 中所有其他类型的基类,它们可以保存引用类型。流是字节序列。

示例

让我们举一个例子来演示 C# 中的预定义引用类型

输出

Explain and contrast value types and reference types in C#

用户定义引用类型

用户定义引用类型包括类、接口和委托。类包含成员和成员函数。它们用于定义具有属性和行为的对象。接口定义了类必须实现的契约。委托代表对方法的引用。

示例

让我们举一个例子来演示 C# 中的用户定义引用类型。

输出

Explain and contrast value types and reference types in C#

C# 中值类型与引用类型的相似之处

C# 中的值类型引用类型之间有几个相似之处。其中一些如下:

  • 值类型和引用类型都有预定义的函数和方法,这些函数和方法用于功能并且可重用。

具有方法的示例值类型

具有方法的示例引用类型

  • 这两种类型都可以作为参数传递给方法或函数。
  • 值类型和引用类型用于数组、列表和字典等集合中,这些集合用于存储和操作数据。
  • 这两种类型都可以为 null。
  • 值类型和引用类型都会实现接口。值类型中的结构体和引用类型中的类会实现接口,这些接口用于实现和定义方法和成员函数。

示例

  • 这两种类型都有默认值。对于值类型,整数的默认值为 0,双精度浮点数的默认值为 0.0,布尔值的默认值为 false。对于一些引用类型,如类,默认值为 null;数组的默认值也为 null。

示例

  • 这两种类型都可以作为方法和函数的返回值。方法既可以返回值类型,也可以返回引用类型。
  • 值类型和引用类型都有构造函数。值类型中的结构体可以有构造函数来初始化变量,引用类型中的类有构造函数。

C# 中值类型与引用类型的区别

C# 中的值类型引用类型之间有几个区别。其中一些如下:

特性 值类型引用类型
内存分配与值类型相关的数据在堆栈上分配。它们是小型、短暂的对象。引用类型在堆上分配。它们用于具有较长生命周期的较大对象。
复印对副本的更改不会影响原始副本。多个引用可以指向同一个对象。
定义值类型在其自身的内存空间中保存数据值。引用类型保存指向另一个包含数据的内存位置的指针。
默认初始化零或 NullNull
类型之间的转换隐式或显式隐式或显式
继承不支持继承。引用类型支持继承。
内存管理由运行时自动管理,当方法退出时,堆栈内存会自动释放。需要垃圾回收进行释放。当不再引用堆内存时,垃圾回收器会回收它。
装箱/拆箱值类型在被视为对象时会被装箱,会产生性能开销。没有装箱/拆箱,因为它们默认是引用类型。
性能由于堆栈分配,它们通常更快,可以减少堆管理的开销。由于堆分配和垃圾回收,它们速度稍慢。
示例Int、float、struct、enum、bool 等。Class、interface、array、string 等。

结论

总之,本文介绍了 C# 中的引用类型。本文详细解释了值类型和引用类型的用法。

C# 中的值类型存储在堆栈上,而引用类型存储在堆上。值类型代表独立的值,而引用类型保存指向存储实际数据的内存位置的引用。值类型由于堆栈分配而更快,而引用类型是堆分配。通过? 修饰符,值类型和引用类型都可以为 null。只有引用类型可以直接参与继承。