目录
一、值类型变量:
直接存储其数据值,主要包含证书类型、浮点类型以及布尔类型等。值类型变量在栈中进行分配,因此效率很高,使用值类型主要目的是为了提高性能。
二、值类型的特征:
- 值类型变量都存储在栈中。
- 访问值类型变量时,一般直接访问其实例。
- 每个值类型变量都有自己的数据副本,因此对一个值类型变量的操作不会影响其他变量。
- 复制值类型变量时,复制的是变量的值,而不是变量的地址。
- 值类型变量不能为null,必须具有一个确定的值。
- 值类型是从System.ValueType类继承而来的类型。
三、引用类型:
引用类型是构建C#应用程序的主要对象类型数据。在应用程序执行的过程中,预先定义的对象类型以new创建对象实例,并存储在堆中。堆是一种由系统弹性配置的内存空间,没有特定大小及存活时间,因此可以被弹性地运用于对象的访问。引用类型就好像代理商,没有自己的商品,被代理的商品就像自己的商品一样。
四、引用类型的特征:
- 必须在托管堆中为引用类型变量分配内存;
- 使用new关键字来创建引用类型变量;
- 在托管堆中分配的每个对象都有与之相关联的附加成员,这些成员必须被初始化;
- 引用类型变量是由垃圾回收机制来管理的;
- 多个引用类型变量可以引用同一对象,在这种情况下,对一个变量的操作会影响另一个变量所引用的同一对象。
- 引用类型被赋值前的值都是null。
五、值类型与引用类型的区别:
值类型直接存储数值,而引用类型存储对其值的引用。值类型相当于现金,要用直接用;引用类型相当于存折,要用得先去银行取。
这两种类型存储在内存的不同地方。值类型在栈中操作,引用类型在堆中分配存储单元。栈在编译时就分配好内存空间,在代码中有栈的明确定义,而堆是程序运行中动态分配的内存空间,可以根据程序的运行情况动态地分配内存大小。
值类型总是在内存中占用一个预定义的字节数,而引用类型的变量则在堆中分配一个内存空间,这个内存空间包含的是对另一个内存位置的引用,这个位置是托管堆中的一个地址,即存放此变量实际值的地方。
六、案例:
/*值类型与引用类型的区别*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyApp
{
class Differ
{
static void Main(string[] args)
{
if (args is null)
{
throw new ArgumentNullException(nameof(args));
}
ReferenceAndValue.Demonstration(); //调用类中的方法
Console.ReadLine();
}
}
public class Stamp //定义一个类
{
public string? Name { get; set; } //定义引用类型
public int Age { get; set; } //定义值类型
}
public static class ReferenceAndValue //定义静态类
{
public static void Demonstration() //定义静态方法
{
Stamp Stamp_1 = new() { Name = "Premiere", Age = 25 }; //实例化
Console.WriteLine("Stamp_1's name:{0}", Stamp_1.Name); //显示值
Console.WriteLine("Stamp_1's age:{0}", Stamp_1.Age); //显示Age值
Stamp Stamp_2 = new() { Name = "Again", Age = 47 }; //实例化
Console.WriteLine("Stamp_2's name:{0}", Stamp_2.Name); //显示值
Console.WriteLine("Stamp_2's age:{0}", Stamp_2.Age); //显示Age值
int age = Stamp_1.Age; //获取值类型Age值
Console.WriteLine("Age's value:{0}", age); //显示age值
Stamp_1.Age = 22; //修改值类型值
Console.WriteLine("Stamp_1's age:{0}", Stamp_1.Age); //显示Age值
Stamp guru = Stamp_2; //获取值
Console.WriteLine("guru's name:{0}", guru.Name); //显示值
Console.WriteLine("guru's age:{0}", guru.Age); //显示值
Console.WriteLine("Stamp_2's name:{0}", Stamp_2.Name); //显示值
Console.WriteLine("Stamp_2's age:{0}", Stamp_2.Age); //显示Age值
Stamp_2.Name = "Again Amend"; //修改引用的值
Console.WriteLine("Stamp_2's name:{0}", Stamp_2.Name); //显示值
}
}
}
/*运行结果:
Stamp_1's name:Premiere
Stamp_1's age:25
Stamp_2's name:Again
Stamp_2's age:47
Age's value:25
Stamp_1's age:22
guru's name:Again
guru's age:47
Stamp_2's name:Again
Stamp_2's age:47
Stamp_2's name:Again Amend */