本文对常用的数据结构:Array, ArrayList,List,IList,ICollection, Stack, Queue, HashTable, Dictionary, IQueryable, IEnumerable等进行详述。
![](https://i-blog.csdnimg.cn/blog_migrate/7e2299be03436ab6c6b62d995663d667.jpeg)
一、Collection(集合)
Collection是数据记录集合,
编写代码过程中,常常需要合适的容器保存临时数据,方便修改和查找,如何选取合适的数据容器,关键在于将执行的数据操作以及数据记录是否大量。
![](https://i-blog.csdnimg.cn/blog_migrate/8044e23d57f564da7b0958c0e8d2291c.jpeg)
二、Array(数组)
特征
1. 固定大小,数组的大小是初始化时决定无法修改的数值。
2. 强类型,存储数据元素类型必须在初始化时指定,因此在运行时,不需要耗费额外的时间来定义数组类型,能够大大提升运行效率。
3. 可使用Foreach关键字实现数组迭代和查找。
因为数组大小是固定的,且是强类型数据结构,因此在运行时只占用很少的内存,运行时效率很高。
![](https://i-blog.csdnimg.cn/blog_migrate/7587c79c21dc783de03e891afc2aac9a.jpeg)
三、ArrayList
1. ArrayList 没有固定的长度,容量可动态增加,可应用于开发人员无法确定数组元素个数等场景,当然这种情况下,在定义结构体的时候会非常耗时。
2. ArrayList 不是强类型,ArrayList中不同元素类型可以不相同,并且需要在运行时根据实际的输入来确定元素类型。因此在运行时消耗内存较多。
3. 可使用Froeach 关键字操作ArrayList。
![](https://i-blog.csdnimg.cn/blog_migrate/5a0f05a2f578ad1e1ccadb08c6b48228.jpeg)
ArrayList支持String,int,以及十进制小数类型。
四、HashTable(哈希表)
HashTable是一种定义关键字的数据结构体,使用哈希表查找数据非常方便,哈希表既不是强类型也不固定大小限制。
![](https://i-blog.csdnimg.cn/blog_migrate/79101ae92d8e9d4564e618790855487a.jpeg)
五、Stack
栈是最典型的数据结构,栈具有优先级划分的数据结构,栈为每个内容项定义优先级,表示每个Item入栈和出栈的优先顺序。因此操作栈中的数据,需要先将数据push 到栈的顶部,需要删除元素必须变成栈顶部,即要遵守后进先出(LIFO)的原则。
栈与哈希表一样既不是强类型也不限制元素个数。
![](https://i-blog.csdnimg.cn/blog_migrate/21e6949864548921a5b8fdd05a1396f8.jpeg)
Push 操作
- //Stack is LIFO: Last in First Out
- System.Collections.Stack objStackPush = new System.Collections.Stack();
-
- //By Push method you can insert item at the top of the stack
- objStackPush.Push("Mahsa");
- objStackPush.Push("Hassankashi");
- this.lblPop.Text = "";
- this.ListBoxStack.DataSource = objStackPush.ToArray();
- this.ListBoxStack.DataBind();
复制代码
Pop操作
- System.Collections.Stack objStackPop = new System.Collections.Stack();
-
- objStackPop.Push("Mahsa");
- objStackPop.Push("Hassankashi");
-
- //By Pop method you can remove item from the top of the stack --> Last in First in
- this.lblPop.Text = objStackPop.Pop().ToString();
-
- this.ListBoxStack.DataSource = objStackPop.ToArray();
- this.ListBoxStack.DataBind();
复制代码
六、Queue
Queue同栈一样也是具有优先级定义的结构体,遵循的规则是先进先出(FIFO),既不是强类型也不具有固定的大小限制。
![](https://i-blog.csdnimg.cn/blog_migrate/95dfa23eea330891ea2ebedda64d48b6.jpeg)
入队操作
- //Queue is FIFO: First in First Out
- System.Collections.Queue objQueue = new System.Collections.Queue();
-
- //By Enqueue method you can insert item at the END of the Queue
- objQueue.Enqueue("Mahsa");
- objQueue.Enqueue("Hassankashi");
- objQueue.Enqueue("Cosmic");
- objQueue.Enqueue("Verse");
-
- this.lblQueue.Text = "";
- this.ListBoxQueue.DataSource = objQueue.ToArray();
- this.ListBoxQueue.DataBind();
复制代码
出队操作
- System.Collections.Queue objQueue = new System.Collections.Queue();
-
- objQueue.Enqueue("Mahsa");
- objQueue.Enqueue("Hassankashi");
- objQueue.Enqueue("Cosmic");
- objQueue.Enqueue("Verse");
-
- //By Dequeue method you can remove item from the BEGINING of the Queue --> First in First out FIFO
- this.lblQueue.Text=objQueue.Dequeue().ToString();
-
- this.ListBoxQueue.DataSource = objQueue.ToArray();
- this.ListBoxQueue.DataBind();
复制代码
入队操作
- System.Collections.Queue objQueue = new System.Collections.Queue();
-
- objQueue.Enqueue("Mahsa");
- objQueue.Enqueue("Hassankashi");
- objQueue.Enqueue("Cosmic");
- objQueue.Enqueue("Verse");
-
- //By Dequeue method you can remove item from the BEGINING of the Queue --> First in First out FIFO
- this.lblQueue.Text=objQueue.Dequeue().ToString();
-
- this.ListBoxQueue.DataSource = objQueue.ToArray();
- this.ListBoxQueue.DataBind();
复制代码
七、List
什么情况下需要使用List?
1. List长度可不固定
2. 当数据为通用类型,List是强类型,List中元素类型不需要等到运行时来确定,这种特性使得List 运行时效率非常高。
3. 可使用Foreach关键字。
因为List不需要设定固定的大小,List灵活度高,且效率高常用于开发过程中。
![](https://i-blog.csdnimg.cn/blog_migrate/5e3eeaecd50c0d2844d56efa7a0db96c.jpeg)
- //Like Array is Strong Type
- //Like ArrayList with No Dimension
- System.Collections.Generic.List<string> strList = new List<string>();
-
- strList.Add("Mahsa");
- strList.Add("Hassankashi");
- strList.Add("Cosmic");
- strList.Add("Verse");
-
- this.ListBoxListGeneric.DataSource = strList;
- this.ListBoxListGeneric.DataBind();
-
- System.Text.StringBuilder str = new System.Text.StringBuilder();
-
- foreach (var item in strList)
- {
- str.Append(" , " + item);
- }
- this.lblList.Text = str.ToString();
复制代码
八、IList
IList 继承了List,包含多种方法的List接口。如果你无法判断代码改动的可能性,可以使用IList接口,减少模块之间的依赖性。IList是接口因此无法被实例化,所以必须使用List来初始化。
- //Ilist can not be instantiate from Ilist , so it should be instantiate from List
- System.Collections.Generic.IList<string> strIList = new List<string>();
-
- strIList.Add("Mahsa");
- strIList.Add("Hassankashi");
- strIList.Add("Cosmic");
- strIList.Add("Verse");
-
- this.ListBoxListGeneric.DataSource = strIList;
- this.ListBoxListGeneric.DataBind();
-
- System.Text.StringBuilder str = new System.Text.StringBuilder();
-
- foreach (var item in strIList)
- {
- str.Append(" , " + item);
- }
- this.lblList.Text = str.ToString();
复制代码
我们一起了解一下具体的类和接口之间的区别。
1. 具体类可继承其他类,并实现一个或多个接口。
2. 在内部类中可以定义变量并赋值,接口中不允许此操作。
3. 具体类可包含构造函数,而接口中不能定义构造函数
4. 抽象类中可包含访问修饰符如public,private等,接口中不能包含。
![](http://www.codeproject.com/KB/cs/832189/Abstract-vs-Interface-CP.jpg)
- //IEnumerable can not be instantiate from Enumerable , so it should be instantiate from List
- System.Collections.Generic.IEnumerable<Employee> empIEnumerable = new List<Employee> {
- new Employee { ID = 1001, Name="Mahsa"},
- new Employee { ID = 1002, Name = "Hassankashi" },
- new Employee { ID = 1003, Name = "CosmicVerse" },
- new Employee { ID = 1004, Name = "Technical" }
- };
-
- this.GridViewIEnumerable.DataSource = empIEnumerable;
- this.GridViewIEnumerable.DataBind();
-
- System.Text.StringBuilder str = new System.Text.StringBuilder();
-
- foreach (Employee item in empIEnumerable)
- {
- str.Append(" , " + item.ID +"-"+item.Name);
- }
- this.lblIEnumerable.Text = str.ToString();
复制代码
九、IEnumerable
IEnumerable常用于遍历集合元素,但是无法修改(删除或添加)数据,使用IEnumberable 会从服务器端将所有数据拷贝到客户端,并进行一定的过滤,如果服务器端有大量数据会造成内存负载超重。
![](https://i-blog.csdnimg.cn/blog_migrate/9b90833da2cf04f8664bca6263e24b26.jpeg)
- //IEnumerable can not be instantiate from Enumerable , so it should be instantiate from List
- System.Collections.Generic.IEnumerable<Employee> empIEnumerable = new List<Employee> {
- new Employee { ID = 1001, Name="Mahsa"},
- new Employee { ID = 1002, Name = "Hassankashi" },
- new Employee { ID = 1003, Name = "CosmicVerse" },
- new Employee { ID = 1004, Name = "Technical" }
- };
-
-
- this.GridViewIEnumerable.DataSource = empIEnumerable;
- this.GridViewIEnumerable.DataBind();
-
- System.Text.StringBuilder str = new System.Text.StringBuilder();
-
- foreach (Employee item in empIEnumerable)
- {
- str.Append(" , " + item.ID +"-"+item.Name);
- }
- this.lblIEnumerable.Text = str.ToString();
复制代码
十、IQueryable
IQueryable与IEnumberable不同的是,当从服务器端加载过量的数据,IQueryable会自动减少应用负载。IQueryable可保证大数据量时应用程序的高性能。IQueryable会先过滤数据,然后发送给客户端。
- DataAccessEntities ctx = new DataAccessEntities();
- var ctx = new DataAccessEntities();
复制代码
![](https://i-blog.csdnimg.cn/blog_migrate/6b0af38057aa2a0ad30b2ee6ad2c59ef.jpeg)
![](https://i-blog.csdnimg.cn/blog_migrate/845fba14c8e925d0cd0a3f70164bc6d5.jpeg)
十一、SQL Profiler:
如何追踪查询语句生成TSQL,生成需要的数据结构体:
Step 1:
- Start -> MS SQL Server 2008 -> Performance Tools -> SQL Server Profiler
复制代码
Step 2:
- SQL Server Profiler -> File -> New Trace
复制代码
![](https://i-blog.csdnimg.cn/blog_migrate/dbbeabe0dbac9fa5bfd523f762deb4d2.jpeg)
Step 3:
输入连接数据库的用户名和密码
![](https://i-blog.csdnimg.cn/blog_migrate/48473f02b90a4d4418d0e160dad486f0.jpeg)
Step 4:
- General (Tab) -> Use the Template: Standard
复制代码
![](https://i-blog.csdnimg.cn/blog_migrate/f8a8752a25b363295552cee19cd1b8ab.jpeg)
Step 5:
- Event Selection (Tab) -> Event : TSQL -> Select : SQL-BatchCompleted | Select Show all Columns
-
- Press Column Filter -> Database Name: Like: "DataAccess"
复制代码
运行
![](https://i-blog.csdnimg.cn/blog_migrate/58e69b61f04025ade0a2de53d8f2e135.jpeg)
Step 6:
查看结果
![](https://i-blog.csdnimg.cn/blog_migrate/e976a0fb97817de3e282ea98fe417628.jpeg)
Step 7:
生成 IEnumerable数据 :
- SELECT
- [Extent1].[ID] AS [ID],
- [Extent1].[Name] AS [Name],
- [Extent1].[Age] AS [Age]
- FROM [dbo].[Employee] AS [Extent1]
复制代码
![](https://i-blog.csdnimg.cn/blog_migrate/23b8ec18ab6d3a6382da1ffdd347f44e.jpeg)
生成 IQueryable :
- SELECT
- [Extent1].[ID] AS [ID],
- [Extent1].[Name] AS [Name],
- [Extent1].[Age] AS [Age]
- FROM [dbo].[Employee] AS [Extent1]
- WHERE 1 = [Extent1].[ID]
复制代码
![](http://www.codeproject.com/KB/cs/832189/Sql-Profiler-8.jpg)
ICollection 继承了IEnumberable,但是IEnumberable是基于索引的,ICollection不基于索引。
![](https://i-blog.csdnimg.cn/blog_migrate/366347e09a168c6466bd9ce4636dd6b7.jpeg)
十二、Stack Generic
入栈:
- //Stack is LIFO: Last in First Out
- //Here is for Push Stack in Generic
- //System.Collections.Stack objStackPush = new System.Collections.Stack();
- //Stack<T> can be instantiated from Stack<T>
-
- System.Collections.Generic.Stack<int> objStackPush = new System.Collections.Generic.Stack<int>();
-
- objStackPush.Push(1);
- objStackPush.Push(2);
-
- this.lblPopGeneric.Text = "";
- this.ListBoxStackGeneric.DataSource = objStackPush.ToArray();
- this.ListBoxStackGeneric.DataBind();
复制代码
Queue Generic
入队:
- //Stack is LIFO: Last in First Out
- //Here is for Pop Stack in Generic
- //System.Collections.Stack objStackPop = new System.Collections.Stack();
- //Stack<T> can be instantiated from Stack<T>
-
- System.Collections.Generic.Stack<int> objStackPop = new System.Collections.Generic.Stack<int>();
-
- objStackPop.Push(1);
- objStackPop.Push(2);
-
- this.lblPop.Text = objStackPop.Pop().ToString();
- this.ListBoxStack.DataSource = objStackPop.ToArray();
- this.ListBoxStack.DataBind();
复制代码
出队:
- //Queue is FIFO: First in First Out
- //Here is for Enqueue Queue in Generic
- //System.Collections.Queue objQueue = new System.Collections.Queue();
- //Queue<T> can be instantiated from Queue<T>
- System.Collections.Generic.Queue<int> objQueue = new System.Collections.Generic.Queue<int>();
- objQueue.Enqueue(1);
- objQueue.Enqueue(2);
-
- this.lblQueue.Text = "";
-
- this.ListBoxQueue.DataSource = objQueue.ToArray();
- this.ListBoxQueue.DataBind();
复制代码
十三、Dictionary 及 IDictionary:
Dictionary 可通用,而哈希表不是通用的。Dictionary定义 <TKey,Tvalue>。IDictionary是Dictionary的接口,如果在后期开发中需要大量修改,建议使用IDictionary。
- System.Collections.Generic.Dictionary<int, string=""> objDictionary = new Dictionary<int, string="">();
-
- objDictionary.Add(1001, "Mahsa");
- objDictionary.Add(1002, "Hassankashi");
- objDictionary.Add(1003, "Cosmicverse");
-
- string str = objDictionary[1002];
-
- this.ListBoxDictionary.DataSource = objDictionary;
- this.ListBoxDictionary.DataBind();</int,>
复制代码