2014-09-26 52 views
7

Bu dizide LINQ'da var. Neden List.Count() ve IEnumerable.Count() farklı sonuçlar döndürüyor?

string[] colors = { "green", "brown", "blue", "red" }; 

ve dönüş 0.

var list = new List<string>(colors); 
IEnumerable<string> q3 = list.Where(c => c.Length == 3); 
list.Remove("red"); 
listBox1.Items.Add("Oh! That is : " + q3.Count()); 

ve diğer dönüş 1.

var list = new List<string>(colors); 
List<string> q3 = list.Where(c => c.Length == 3).ToList(); 
list.Remove("red"); 
listBox1.Items.Add("Oh! That is : " + q3.Count()); 

gerçekleşmesi Neden bu kod? Liste ile kabul edilemez arasındaki fark nedir?

+3

[Ertelenmiş yürütme] (http://blogs.msdn.com/b/charlie/archive/2007/12/09/deferred-execution.aspx) aradığınız terimdir. Birçok [Enumerable'da LINQ yöntemleri] (http://msdn.microsoft.com/en-us/library/system.linq.enumerable_methods (v = vs.100) .aspx) tembel olarak yürütülür. –

+0

olası yinelenen [IEnumerable ve Array, IList ve Liste arasındaki fark nedir?] (Http://stackoverflow.com/questions/764748/whats-the-difference-between-ienumerable-and-array-ilist-and-list – bit

+3

@bit: Gerçekten bunun bir kopyası değil. Bu gerçekten LINQ'da ertelenmiş infazla ilgili. –

cevap

0

IEnumerable bir arabirimdir ve bir liste bir sınıftır.
Ve IEnumerable değerleri kaydedebilir, ancak değerleri ekleme veya çıkarma gibi düzenleyemezsiniz.

Ayrıca, .ToList() yaptığınızda, db öğelerinden birini seçerseniz, sorgulama veritabanında gerçekleştirilir.

19

Where yöntem istediğiniz veritabanlarını değil - sadece veri istendiğinde sonra yürütülen bir sorgu, inşa eder. Bu ertelenmiş yürütme olarak bilinir. Dolayısıyla, ilk snippet'inizde, filtre yalnızca Count() çağrıldığında uygulanır - red öğesinden kaldırıldıktan sonra.

İkinci kod parçasında, ToList() numaralı aramanız, yeni bir liste oluşturmak için sorguyu hemen yürütülmeye zorlar. Bu daha sonra orijinal listeden tamamen bağımsızdır - bu yüzden bir öğeyi orijinal listeden kaldırmak sonucu etkilemez.

Bu q3 beyanı türüne bağımlı değildir - önemli fark sadeceToList() için çağrıdır. Eğer ikinci pasajı değiştirmek Yani eğer:

var list = new List<string>(colors); 
IEnumerable<string> q3 = list.Where(c => c.Length == 3).ToList(); 
list.Remove("red"); 
listBox1.Items.Add("Oh! That is : " + q3.Count()); 

... Aynı etkiyi göreceksiniz. Sorgu, öğe kaldırılmadan önce yürütülür; bu noktada, orijinal liste, q3'un içeriğiyle ilgisizdir.

LINQ oturumları hakkında daha fazla bilgi için, Edulinq blog series numaralı telefonu okumak isteyebilirsiniz.