作者:奋怒的小超_656 | 来源:互联网 | 2023-10-10 12:36
内存中存在2大区域——堆,栈;堆栈概念栈栈在编译时分配好内存空间堆随程序运行情况动态分配内存的大小引用类型和值类型值类型值类型是在栈中分配的一个内存空间,诸如int,float,c
内存中存在2大区域——堆,栈;
堆栈概念
栈
栈在编译时分配好内存空间
堆
随程序运行情况动态分配内存的大小
引用类型 和 值类型
值类型
值类型 是在栈中分配的一个内存空间,诸如int,float,char都是值类型,值类型的数据就写在栈分配的那一个内存空间内(但这话说得不绝对,后面我细细道来)
引用类型
引用类型 是先在栈中分配一个内存空间,然后在堆中分配一个内存空间,把数据写入堆的空间中,再把这块堆的地址赋给栈空间,换种方法说:栈中存的是一个指针,指向堆中的某个地址;而堆中那块地址存储的才是真实值。
编程时可能遇到的问题
- 类中的基础类型的值也是写在堆中的
// 定义一个类
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
}
用Student
类定义一个对象,主程序中尝试修改这个对象
static void Main(string[] args)
{
Student s2 = new Student { Id = 2,Name = "2"};
Student s3 = s2;
s3.Id = 10;
Console.WriteLine($"{s3.Id} {s2.Id}");// 打印结果10 10
Console.ReadLine();
}
看,Id
是值类型int
,反而修改了s3
的Id
,s2
的也跟着变了;这就说明即便是值类型,在类对象中也是存储在堆中而非栈中的。单独使用才在栈中存在(如下代码示例)
static void Main(string[] args)
{
int i = 10;
int j = i;
i = 0;
Console.WriteLine($"{i} {j}");// 打印结果0 10,j的数值没有受到i改变的影响
Console.ReadLine();
}
- 浅拷贝类时修改其中一个的某一属性后,另一个类变化
这种情况的BUG是最常见的,举个例子// 定义一个类
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
}
static void Main(string[] args)
{
Student s2 = new Student { Id = 2,Name = "2"};
Student s3 = s2;
s3.Name = "a";
Console.WriteLine($"{s3.Name} {s2.Name}");// 打印结果a a
Console.ReadLine();
}
看出问题没?s3
是浅拷贝s2
来的,s3
后面改name
属性,结果s2
也跟着改了。因为s3,s2都定义在栈中,两者存储的地址却是指向同一堆区域,这就是浅拷贝——牵一发动全身!
ps:分清楚C#中的引用类型 和 值类型 有利于在今后编程中快速定位一些隐藏的BUG
本文来自博客园,作者:一口吃不成胖子,转载请注明原文链接:https://www.cnblogs.com/JarryShu/p/16927157.html