在介紹tolist()的時候我先個大家介紹一下linq的延遲加載:
1 var products = new List<Product> 2 { 3 new Product { Name = "CD Player", Id = 1, Category = "Electronics" }, 4 new Product { Name = "DVD Player", Id = 2, Category = "Electronics" }, 5 new Product { Name = "Blu-Ray Player", Id = 3, Category = "Electronics" }, 6 new Product { Name = "LCD TV", Id = 4, Category = "Electronics" }, 7 new Product { Name = "Wiper Fluid", Id = 5, Category = "Automotive" }, 8 new Product { Name = "LED TV", Id = 6, Category = "Electronics" }, 9 new Product { Name = "VHS Player", Id = 7, Category = "Electronics" }, 10 new Product { Name = "Mud Flaps", Id = 8, Category = "Automotive" }, 11 new Product { Name = "Plasma TV", Id = 9, Category = "Electronics" }, 12 new Product { Name = "Washer", Id = 10, Category = "Appliances" }, 13 new Product { Name = "Stove", Id = 11, Category = "Electronics" }, 14 new Product { Name = "Dryer", Id = 12, Category = "Electronics" }, 15 new Product { Name = "Cup Holder", Id = 13, Category = "Automotive" }, 16 }; 17 18 // select all electronics, there are 7 of them 19 IEnumerable<Product> electronicProducts = products.Where(p => p.Category == "Electronics"); 20 21 // now clear the original list we queried 22 products.Clear(); 23 24 // now iterate over those electronics we selected first 25 Console.WriteLine(electronicProducts.Count());
許多擴展方法(包括Where() )的查詢結果是創建一個迭代器通過移動列表來執行查詢。 因此,此時的electronicProducts不是List<Product>,只是IEnumerable<Product>,它會在您使用這個列表時動態求值. 這就是LINQ中強大的延遲執行,在你需要結果前,都不會對表達式求值。 此時我們可以去查詢electronicProducts,這樣我們就可以得到結果列表!
但是如果我們換一種寫法這個值就會是7:
1 var electronicProducts = products.Where(p => p.Category == "Electronics").ToList();
現在, List<T>代替 electronicProducts 作為IEnumerable<T> 動態執行的原始集合,這將是另一個新的集合,修改不會影響原來的集合。
當然,這有優點也有缺點。 通常,如果你只是要遍歷的結果和過程,你不需要(也不想)將它存儲在一個單獨的列表,這只會浪費內存,后來還需要垃圾收集。 然而,如果你想保存子集,並將它分配給另一個類,ToList()是非常方便的,你不需要擔心改變原來的集合。
ToList()內存消耗
tolist和lazy load是對立的 ,tolist是直接將linq語句的執行結果放於list集合中,直接將結果存放在內存中,所以數據量大的時候,使用tolist要謹慎。