C# - 值类型和引用类型(Value Type and Reference Type)
本文关键字:Type Value and Reference 引用类型 类型 | 更新日期: 2023-09-12 17:38:31
在 C# 中,这些数据类型根据它们在内存中存储其值的方式进行分类。C# 包括以下类别的数据类型:
- 值类型
- 引用类型
- 指针类型
值类型
如果数据类型将数据值保存在自己的内存空间中,则该数据类型是值类型。这意味着这些数据类型的变量直接包含值。
例如,考虑整数变量int i = 100;
系统在分配给变量i
的内存空间中存储100。下图说明了如何将 100 存储在内存 (0x239110) 中某个假设位置的"i":
值类型变量的内存分配
以下数据类型均为值类型:
- bool
- bool
- byte
- char
- decimal
- double
- enum
- float
- int
- long
- sbyte
- short
- struct
- uint
- ulong
- ushort
传递值类型变量
将值类型变量从一个方法传递到另一个方法时,系统会在另一个方法中创建变量的单独副本。如果值在一个方法中发生了更改,则不会影响另一个方法中的变量。
Example: Passing Value Type Variables
static void ChangeValue(int x)
{
x = 200;
Console.WriteLine(x);
}
static void Main(string[] args)
{
int i = 100;
Console.WriteLine(i);
ChangeValue(i);
Console.WriteLine(i);
}
输出:
100200
100
在上面的示例中,Main()
方法中的变量i
保持不变,即使我们将它传递给 ChangeValue()
方法并更改其值。
引用类型
与值类型不同,引用类型不直接存储其值。相反,它存储存储值的地址。换句话说,引用类型包含指向保存数据的另一个内存位置的指针。
例如,请考虑以下字符串变量:
string s = "Hello World!!";
下图显示了系统如何为上述字符串变量分配内存。
引用类型变量的内存分配
如上图所示,系统在内存(0x803200)
中为变量s
选择一个随机位置。
变量s
的值是 0x600000
,这是实际数据值的内存地址。因此,引用类型存储存储实际值的位置的地址,而不是值本身。
以下是引用类型数据类型:
- String
- 数组(即使它们的元素是值类型)
- 类
- 委托
传递引用类型变量
将引用类型变量从一个方法传递到另一个方法时,它不会创建新的副本;而是传递变量的地址。因此,如果我们更改方法中变量的值,它也将反映在调用方法中。
Example: Passing Reference Type Variable
static void ChangeReferenceType(Student std2)
{
std2.StudentName = "Steve";
}
static void Main(string[] args)
{
Student std1 = new Student();
std1.StudentName = "Bill";
ChangeReferenceType(std1);
Console.WriteLine(std1.StudentName);
}
输出:
Steve在上面的示例中,我们将Student
对象std1
传递给 ChangeReferenceType()
方法。在这里,它实际上传递了std1
的内存地址。
因此,当ChangeReferenceType()
方法更改StudentName
时,它实际上是在更改std1
对象的StudentName
,因为std1
和std2
都指向内存中的同一地址。
String 是一种引用类型,但它是不可变的。这意味着一旦我们分配了一个值,它就无法更改。如果我们更改字符串值,则编译器会在内存中创建一个新的字符串对象,并将变量指向新的内存位置。 因此,将字符串值传递给函数将在内存中创建一个新变量,并且函数中值的任何更改都不会反映在原始值中,如下所示。
Example: Passing String
static void ChangeReferenceType(string name)
{
name = "Steve";
}
static void Main(string[] args)
{
string name = "Bill";
ChangeReferenceType(name);
Console.WriteLine(name);
}
输出:
BillNull
引用类型变量的默认值在未初始化时null
。
Null
意味着不引用任何对象。
Null 引用类型
值类型变量不能为 null,因为它保存值,而不是内存地址。
C# 2.0 引入了