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