2014-09-26 2 views
7

이 배열은 LINQ에 있습니다. List.Count() 및 IEnumerable.Count()가 다른 결과를 반환하는 이유는 무엇입니까?

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

과 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()); 

및 기타 수익 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()); 

이 일이 왜이 코드? 목록과 Ienumerable 사이의 차이점은 무엇입니까?

+3

[지연 실행] (http://blogs.msdn.com/b/charlie/archive/2007/12/09/deferred-execution.aspx)은 검색중인 용어입니다. 'Enumerable'의 많은 [LINQ 메서드] (http://msdn.microsoft.com/en-us/library/system.linq.enumerable_methods (v = vs.100) .aspx)가 지연 실행됩니다. –

+0

[IEnumerable과 Array, IList 및 List의 차이점은 무엇입니까?] (http://stackoverflow.com/questions/764748/whats-the-difference-between-ienumerable-and-array-ilist-and-list)) – bit

+3

@bit : 정말 그 복제본이 아닙니다. 이것은 LINQ에서 연기 된 실행에 관한 것입니다. –

답변

0

IEnumerable은 인터페이스이고 목록은 클래스입니다.
IEnumerable은 값만 저장할 수 있지만 값을 추가하거나 제거하는 것과 같이 편집 할 수는 없습니다.

.ToList() 또한 db에서 항목을 선택하면 쿼리가 데이터베이스에서 수행되고 있습니다.

19

Where 방법은 쿼리를 실행하지 않습니다 - 그냥 데이터가 요청 될 때 다음 실행되는 쿼리를 작성합니다. 이를 지연 실행이라고합니다. 따라서 첫 번째 스 니펫에서는 Count()이 호출 될 때만 필터가 적용됩니다. 이후로 red 항목이 제거되었습니다.

두 번째 조각에서 ToList()을 호출하면 쿼리가 즉시 실행되어 새 목록이 작성됩니다. 이것은 원래 목록과 완전히 독립적입니다. 따라서 원래 목록에서 항목을 제거해도 결과에는 영향을 미치지 않습니다.

q3의 선언 형식에 의존하지입니다 - 중요한 차이는 단지ToList()에 대한 호출입니다. 따라서 두 번째 스 니펫을 다음과 같이 변경하면

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()); 

... 같은 효과가 나타납니다. 항목이 제거되기 전에 쿼리가 실행되고 원래 목록은 q3의 내용과 관련이 없습니다.

LINQ의 자세한 내용은 Edulinq blog series을 읽어보십시오.

관련 문제