本节内容为List,ArrayList,和Dictionaryhtml
在此前的文章中咱们学习了数组的使用,可是数组有一个很大的问题就是存储空间不足,咱们一般的解决方法就是定义一个绝对够用的数组,这一般很大,可是这样就形成了内存的损失。咱们老是但愿有一个根据需求动态更变的数组进行存储。在上一节中的综合题中已经隐隐约约引出了List的概念。这一讲咱们会详细的讲解List。git
同时,有时候咱们但愿数组不仅仅的存储咱们的数据。例如我但愿有那么一些数据:github
某人的成绩单以下:数组
对于这些数据,咱们使用数组并不能很好的反馈这些成绩,这个时候咱们须要使用咱们的字典进行存储。安全
正如上文所言,数组是一段连续存储空间,访问速度很是快,可是必须指定大小,这个时候咱们可使用ArrayList进行使用。ArrayList是位于System.Collections的一个类,继承与IList接口,提供了数据的操做。它比数组更优的地方是,它不须要指定任何的大小和类型,直接使用便可。ide
ArrayList al = new ArrayList(); al.Add("test"); al.Add(1234); //修改数据 al[1] = 4; //移除数据 al.RemoveAt(0); //插入数据 al.Insert(0, "qwe");
看起来很是好用对吧,能够插入不一样数据而且修改。可是其实这是很是损失性能的一个操做。由于在ArrayList中插入不一样类型的数据是是容许的,可是在处理后续数据的时候,ArrayList会将内部全部的数据当成Object类型进行处理,所以在每个数据进行遍历的时候,都会发生装箱与拆箱的操做,在上一讲咱们讨论过,频繁的装拆箱是极其损耗性能的。所以,ArrayList在实际状况下并不常用。性能
为了解决ArrayList中类型不一样致使的不安全和装拆箱,咱们使用泛型List类。List类是ArrayList类的泛型等效类,它的大部分用法都与ArrayList类似,由于List类也继承了IList接口。最关键的区别在于,在声明List集合时,咱们同时须要为其声明List集合内数据的对象类型,也就是泛型参数。咱们在 初级篇的综合习题中已经隐约引出了关于List的部份内容。对于List,它的定义以下:学习
List<T> list = new List<T>(); list.Add(new T()); list[0]; list.Remove(T);
对于List,它实现了一个很是重要的接口——IEnumerable,这意味着List支持使用foreach循环进行遍历内部元素。不过使用foreach的时候,下列操做时不合法的:ui
foreach(var item in MyList) { MyList.Remove(item);//不过我相信没有人那么干,可是.... //这种操做我不止一次见过有人问我 if(item.something == something) { MyList.Remove(item); } }
这个时候,你须要往回仔细的回忆咱们以前foreach循环的讲解,在foreach循环中经过这种方式动态的删除一个元素是不合法的,为何?由于foreach循环会调用MoveNext()方法,你能够想象一下一个节点连着一个节点成为了一串集合体,你每次只能向后访问一个节点,也就意味着你必须知晓前一个节点才能够访问后一个节点,假设你访问到某节点的时候,你删除了它,那么后续的节点访问都没法被访问。有没有解决的方法呢?固然有,可是你只能使用for循环,List中有一个属性叫作Count,这个表明着当前List中所拥有的全部元素的个数,而且List实现了索引器,也就是说,List能够经过相似于MyList[0]的方式访问,这个时候,你使用for循环动态删除应当以下:spa
for(int i =0;i<MyList.Count;i++) { if(MyList[i].something == something) { MyList.Remove(MyList[i]); } }
你确定有过简介中提到过的需求。不少时候单纯的索引值没有办法给咱们提供更多的信息,咱们老是倾向于使用一个键值对的方式进行存储数据。那么Dictionary将会很好的解决你的问题。它的基本结构是由两个泛型参数进行修饰,Dictionary<TKey,TValue>,前面是键的类型,后面是值的类型,你也能够把Dictionary理解成一种特殊的集合。它的使用以下:
Dictionary<string,string> dict = new Dictionary<string,string>(); dict.Add("广东","广州"); dict.Add("江西","南昌"); dict["江西"]; dict.remove("广东");
一般来讲,咱们不多使用foreach直接访问Dictionary,由于迭代的结果就是一个个键值对,通常Dictionary的Value以List居多,所以通常都是迭代Key。
Dictionary大部分操做和List是接近的,这里就不过多阐述。
这两个接口时集合(List)的实现的重要接口,IEnumerable提供了迭代功能,IList提供了相应的集合操做,咱们从元数据中就能够很好的学习他们。
它在元数据的定义以下:
public interface IEnumerable<out T> : IEnumerable { // // 摘要: // Returns an enumerator that iterates through the collection. // // 返回结果: // An enumerator that can be used to iterate through the collection. IEnumerator<T> GetEnumerator(); }
咱们能够很清楚的发现泛型参数中有out关键字修饰,也就是说,咱们的IEnumerable是支持协变的。咱们能够很轻松的将IEnumerable类型的数据转换成其余数据,例如:
IEnumerable<string> strs = new IEnumerable<string>(); IEnumerable<object> obj = strs;
所以我一般在使用的时候,我会推荐使用IEnumerable来代替List的一些数据操做。
老规矩,先看看元数据
public interface IList<T> : ICollection<T>, IEnumerable<T>, IEnumerable { //省略 }
这里就能够发现IList并不支持协变,属于不变式,那么下列用法是不合法的:
IList<string> strs = new IList<string>(); IList<object> obj = strs;
若是个人文章帮助了您,请您在github .NET Core Guide项目帮我点一个star,在博客园中点一个关注和推荐。
原文出处:https://www.cnblogs.com/WarrenRyan/p/11294784.html