引用类型和值类型
概念:
值类型直接存储其值,而引用类型存储对其值的引用。部署:托管堆上部署了所有引用类型
引用类型:基类为Object
值类型:均隐式派生自System.ValueType
值类型有:int struct short byte long float bool char 统称为值类型。
引用类型:string 和 class 统称为引用类型。
值类型变量声明后,不管是否已经赋值,编译器为其分配内存。
引用类型当声明一个类时,只在栈中分配一片内存用于容纳一个地址,而此时并没有为其分配堆上的内存空间。当使用new 创建一个类的实例时,分配堆上的空间,并把堆上空间的地址保存到站上分配的小片空间中。
值类型的实例通常是在线程栈上分配的(静态分配),但是在某些情形下可以储存在堆中。
引用类型的对象总是在进程中分配。(动态分配)
值类型在栈内分配空间大小因变量类型而异
引用类型在栈的空间大小相同。
引用类型在栈中存储一个引用,其实际的存储位置位于托管堆,简称引用类型部署在托管堆上。而值类型总是分配在它声明的地方:作为字段时,跟随其所属的变量(实例)存储。储存在栈上。(栈的内存时自动释放的,堆内存时.Net中会由GC来自动释放)
String类型直接继承自Object,这使得它成为一个引用类型,也就是说线程上的堆栈上不会驻留有任何字符串。 这是一个值类型的赋值,但string是一个引用类型。 String被分配在堆上,而不是栈上。
引用类型和值类型都继承自System.Object类。不同的是,几乎所有的引用类型都直接从System.Object继承,而值类型则继承其子类,即 直接继承System.ValueType。即System.ValueType本身是一个类类型,而不是值类型。其关键在于ValueType重写了Equals()方法,从而对值类型按照实例的值来比较,而不是引用地址来比较。
数据结构
Array 数组 int【】 arr
特点:
数组是一块连续的内存空间,以下标来描述空间的位置。下标从0开始,最大下标为数组长度-1
数组的元素都是变量,变量的类型为定义数组时的类型
数组创建后对每个元素进行初始化
数组创建后,不能改变
优点:
按照索引查询元素速度快。
能存储大量数据。
按照索引遍历数组方便。
缺点:
根据内容查找元素度慢。
数组的大小一经确定不能改变
数组只能存储一种类型的数据
增加,删除元素效率慢
List<T>泛型集合
优点
即确保了类型安全。
也取消了装箱和拆箱的操作。
它融合了Array可以快速访问的优点以及ArrayList长度可以灵活变化的优点。
缺点
在性能上不如数组快。
Dictionary<K,T> 字典
特点 字典是类型安全的 key值唯一
优点
查找速度快
dic = dic .OrderByDescending(r => r.Value).ToDictionary(r => r.Key, r => r.Value);
ArrayList 泛型数组
优点不必再声明ArrayList时指定它的长度,这是由ArraayList对象的长度时按照其中存储的数据来动态增长与缩减的。
ArrayList可以存储不同的元素。这是由ArrayList会把它的元素都当作Object来处理。因此,加入不同类型的元素是允许的。
缺点
ArrayList不是类型安全的。因为把不同的类型都当作Object来做处理,很有可能会再使用ArrayList时发生不可避免的当插入值类型时会发生装箱操作,在索引取值时会发生装箱操作,在索引取值时会发生拆箱操作。
LinkedList 链表
特点 存储在内存的空间不一定连续
1.向链表中插入或删除节点无需调整结构的容量。因为本身不是连续存储而是靠各对象的指针所决定,所以添加元素和删除元素都要比数组要有优势。
2.链表适合在需要有序的排序的情境下增加新的元素,这里还拿数组做对比,例如要在数组中间某个位置增加新的元素,则可能需要移动很多元素,而对于链表而言可能只是若干元素的指向发生变化而已。
3.有优点就有缺点,由于其在内存空间中不一定是连续排列,所以访问时候无法利用下标,而是必须从头结点开始,逐次遍历下一个节点直到寻找到目标。所以当需要快速访问对象时,数组无疑更有优势。