1、值类型
值类型就是直接将内存存储在栈内,由系统自动释放资源的数据类型。也就是说直接存储值
特点
① 值存储在栈中
③ 值类型不可能有派生出来新的类型:所有的值类型均隐式派生自SystemValueType
④ 值类型不可能包含null值
⑤ 每种值类型均有一个隐式的默认构造函数来初始化该类型的默认值
2、引用类型
由类型的实际值引用表示的数据类型。就是说引用类型存储对值的引用
特点
① 值存储在堆中,地址存储在栈中
② 引用类型变量的赋值只复制对对象的引用,不复制对象本身
3、哪些是值类型,哪些是引用类型呢?
4、引用类型与值类型的区别
(1) 值存放位置的区别
值类型的值存放在栈上
引用类型的值存放在堆上,将地址存在放栈上
那么存放的位置不同会产生什么结果呢?举个例子。就以结构代表值类型,类代表引用类型类来举例:其中Student是结构——值类型,person是类——引用类型
static void Main(string[] args)
{
Person p1 = new Person(20,'男');
Person p2 = new Person();
p2 = p1;//令p2=p1
p2.Age = 100;
p2.Gender = '女';
Student s1 = new Student(20,'男');
Student s2 = new Student();
s2 = s1;
s2.Age = 100;
s2.Gender = '女';
Console.WriteLine("{0},{1},{2},{3}",p1.Age, p1.Gender, p2.Age, p2.Gender);
Console.WriteLine("=============");
Console.WriteLine("{0},{1},{2},{3}", s1.Age, s1.Gender, s2.Age, s2.Gender);
Console.ReadKey();
}
输出的结果如下:
①、当为值类型,将值存放在栈上时,也就是student的时候:
从这里可以都看出:
① 因为值存在于栈中,所以值类型的变量声明后,无论是否赋值,编译器都会为其分配内存空间
②每个变量的内存空间大小可以不同,用来直接存储数据本身(存放到栈上)。
③当数据被释放时,期内存空间将会被回收。
④ 每进行一次赋值操作,都会创建一个新对象,为其分配内存存储数据。
②、当为引用类型,将地址存在栈上,将值存在堆上,也就是person的时候:
从这里可以都看出:
① 引用类型的变量只是对数据的引用,申请引用型变量后,内存从栈上分配一个空间来存放引用地址,一般一样大小,然后这个地址是指向堆里面的值的
②当新的变量的值在堆中存在时,堆中不会增加一个相同的值,只会在栈总添加一个内存存放地址。。
③变量并不会在创建他们的方法结束时释放内存空间,他们所占用的内存会被CLR中的垃圾回收机制释放。
(2) 速度的区别
值类型存取速度快,引用类型存取速度慢
(3) 来源的区别
值类型继承自System.ValueType,引用类型继承自System.Object
(3) 用途的区别
值类型表示实际数据,引用类型表示指向存储在内存堆中的数据的指针或引用。
4、结构和类添加构造函数的区别
(1) 添加构造函数时区别
结构:必须把所有字段都必须全部赋值。就是说有3个字段,必须给3个全部赋值
类:构造函数可以给任意个字段赋值然后写构造函数
(2) 添加构造函数后的区别
共同点:都有一个默认的无参数的构造函数
结构:添加了有参数的构造函数,默认的无参数的构造函数依然可以使用
类:添加了有参数的构造函数,默认的无参数的构造函数就不存在了
5、堆和栈的区别
栈是编译期间就分配好的内存空间,因此你的代码中必须就栈的大小有明确的定义;局部值类型变量、值类型参数等都在栈内存中
堆是程序运行期间动态分配的内存空间,可以根据程序的运行情况分配堆内存的大小;