| 一、概述: 軟件開(kāi)發(fā)過(guò)程中不可避免會(huì)用到集合,C#中的集合表現(xiàn)在數(shù)組和若干集合類。不管是數(shù)組還是集合類都有若干優(yōu)點(diǎn)。這樣如何使用集合是我們開(kāi)發(fā)過(guò)程中不可或缺的技巧。 二、C#中集合介紹: 
 
 在上圖中可以看見(jiàn)C#集合分類: 集合分為線性和非線性(很少用),這里我們終點(diǎn)介紹線性集合。 1. 如果集合的數(shù)目固定并且不涉及轉(zhuǎn)型,使用數(shù)組效率高,否則就是用List<T>。 2. 棧滿足先進(jìn)后出原則,隊(duì)列滿足先進(jìn)先出。 3. 數(shù)據(jù)字典:存儲(chǔ)的是鍵值對(duì),值基于鍵的散列碼的基礎(chǔ)進(jìn)行存儲(chǔ)。字典對(duì)象包含集合元素存儲(chǔ)桶組成,每一個(gè)存儲(chǔ)桶與基于該元素的鍵的哈希值關(guān)聯(lián)。 4. 雙向鏈表:當(dāng)我們覺(jué)得集合中插入和刪除數(shù)據(jù)速度慢的時(shí)候就可以考慮雙向鏈表。 三、C#中集合使用: 1.元素?cái)?shù)量可變的情況下不應(yīng)該使用數(shù)組:存在裝箱和開(kāi)辟空間 2. 多數(shù)情況使用foreach進(jìn)行循環(huán)遍歷: 1)foreach提供了簡(jiǎn)單的迭代器語(yǔ)法。 2)自動(dòng)將代碼置入try-finally塊。 3)若類型實(shí)現(xiàn)了Dispose接口,它循環(huán)結(jié)束后自動(dòng)調(diào)用Dispose方法。 3. froeach不能代替for:froeach只支持迭代不支持對(duì)集合進(jìn)行增刪操作。 4. 盡量使用泛型集合代替非泛型集合:可以記錄避免裝箱和拆箱操作。 5. 確保集合線程安全:建議使用線程鎖 static List<Person> list = new List<Person>() { new Person(){Name="Abel",Age=26}, new Person(){Name="Topmson",Age=26}, new Person(){Name="Erwin",Age=27}, new Person(){Name="Lucy",Age=20} }; static AutoResetEvent autoset = new AutoResetEvent(false); static object sycObj = new object(); static void Main(string[] args) { Thread t1 = new Thread(() => { autoset.WaitOne();//保證t2運(yùn)行后在運(yùn)行此段代碼 lock (sycObj) { foreach (Person item in list) { Console.WriteLine("姓名" + item.Name); Thread.Sleep(1000); } } }); t1.Start(); Thread t2 = new Thread(() => { //通知t1可以執(zhí)行代碼 autoset.Set(); Thread.Sleep(1000);//確保刪除操作在迭代過(guò)程中 lock (sycObj) { list.RemoveAt(2); Console.WriteLine("刪除成功!"); } }); t2.Start(); Console.ReadKey(); } class Person { public string Name { get; set; } public int Age { get; set; } } 6.查詢List<T>使用Lambda表達(dá)式并使用匿名類型存儲(chǔ)Linq查詢結(jié)果: public class LinqToList { private List<People> peopleList=new List<People>(); public static LinqToList getInstance() { return new LinqToList(); } public void setPeopleList() { peopleList.Add(new People() { Name = "王艷麗", Age = 12, Sex = "男" }); peopleList.Add(new People() { Name = "王小花", Age = 18, Sex = "女" }); peopleList.Add(new People() { Name = "張三", Age = 22, Sex = "男" }); peopleList.Add(new People() { Name = "莉莉絲", Age = 50, Sex = "女" }); peopleList.Add(new People() { Name = "趙云", Age = 34, Sex = "男" }); peopleList.Add(new People() { Name = "王二麻子", Age = 66, Sex = "女" }); peopleList.Add(new People() { Name = "李四", Age = 24, Sex = "男" }); peopleList.Add(new People() { Name = "小命", Age = 19, Sex = "女" }); } public List<People> getPeopleList() { List<People> list=new List<People>(); //var query = from people in this.peopleList // where people.Name.Length == 3 && // people.Name.StartsWith("王") // select people; var query = this.peopleList.Where(P => P.Name.Length == 3 && P.Name.StartsWith("王")); 7.理解延遲求值和主動(dòng)求值之間的區(qū)別: List<int> list = new List<int>() { 0, 1, 2, 3, 4, 5,6,7,8,9 }; var lazy = list.Where(L => L > 5); var eager = list.Where(L => L > 5).ToList<int>(); list[0] = 10; Console.WriteLine("lazy:"); foreach (var item in lazy) { Console.WriteLine("{0};", item); } Console.WriteLine("eager:"); foreach (var item in eager) { Console.WriteLine("{0};", item); } Console.ReadKey(); 輸出: 對(duì)查詢調(diào)用ToList,ToArray等方法,將會(huì)使其立即執(zhí)行查詢,不會(huì)等在迭代的時(shí)候執(zhí)行查詢。 8. 區(qū)別LINQ查詢中的IEnumerable<T>和IQueryable<T> LINQ查詢方法一共提供了兩類擴(kuò)展方法,在System.Linq命名空間下有兩個(gè)靜態(tài)類: Enumerable類它針對(duì)繼承了IEnumerable<T>接口的集合類進(jìn)行擴(kuò)展;用于本地?cái)?shù)據(jù)源查詢。 Queryable類它針對(duì)繼承了IQueryable<T>接口的集合類進(jìn)行擴(kuò)展;用于遠(yuǎn)程數(shù)據(jù)源查詢。 9.使用LINQ取代集合中的比較器和迭代器:想想SQL就能理解,他們不需要這些。 10.在LINQ查詢中避免不必要的迭代: 例如:返回年齡等于20的一個(gè)元素即可: 方法一:from c in list where c.Age==20 Select c 方法二:(from c in list where c.Age==20 Select c).First() 
 | 
|  |