2013-11-21 5 views
58

때때로 ReSharper에서 대해 경고 : IEnumerable을ReSharper에서의 예제 코드는

가능한 여러 열거

an SO question on how to handle this issue을있다, 그리고 ReSharper에서 사이트도 일 here을 설명합니다.

IEnumerable<string> names = GetNames().ToList(); 

내 질문이 특정 제안에 관한 것입니다 :이 여전히 2 - 각 루프에 두 번 컬렉션을 열거 발생하지 않습니다 대신이 작업을 수행 할 것을 몇 가지 예제 코드가?

답변

146

GetNames()IEnumerable을 반환합니다. 그래서 당신은 그 결과를 저장하는 경우 : 그럼 당신은 foo 열거마다의 GetNames() 방법을 다시 호출

IEnumerable foo = GetNames(); 

(문자 그대로, 내가 제대로 세부 사항을 설명하는 링크를 찾을 수 있지만, IEnumerable.GetEnumerator()을 볼 수 없습니다).

ReSharper에서이를보고하고, 목록에서이를 구체화하여, 예를 들어, 로컬 변수에 GetNames()을 열거의 결과를 저장하기 위해 당신을 제안 :

IEnumerable fooEnumerated = GetNames().ToList(); 

것은 이것은 GetNames() 결과가 있는지 확인합니다 fooEnumerated을 참조하는 한 한 번만 열거됩니다.

일반적으로 GetNames() (느린) 데이터베이스 호출을 수행하는 경우와 같이 일반적으로 한 번만 열거하기 때문에 문제가됩니다.

결과가 목록에 표시되므로 더 이상 fooEnumerated을 두 번 열거하지 않아도됩니다. 메모리 내리스트를 두 번 반복 할 것이다.

+0

가능한 여러 열거! 그것은 그것을 설명합니다. – user2250250

+0

아니요. GetEnumerator() 메서드는 foreach 루프에서만 한 번 호출됩니다. 진짜 이유는 더러운 데이터의 위험 때문입니다. 예를 들어 GetNames()에는 SQL 쿼리가 있지만 IEnurable을 반환하는 쿼리 만 있습니다. .ToList()를 호출하면 모든 데이터가 메모리에 저장되므로 더티 데이터의 위험이 거의 없습니다.그러나 2 루프 오 퍼 레이션 사이에 많은 시간이 있으면 매번 SQL을 데이터베이스로 전송하면 더러운 데이터가 발생할 위험이 큽니다. –

+0

@SunRobin 이것은 단순한 형태로 진실을 제시하는 답변이며, 여기에 언급되어 있습니다. 나는 그것을 개선하기 위해 아직 주변에 가지 못했다. "더티 데이터"를 사용하려면 추가 설명이 필요할 수 있습니다. – CodeCaster

4

네, 의심의 여지없이 두 번 열거 할 것입니다. 요점은 GetNames()이 계산하기에 매우 비싼 lazy linq 쿼리를 반환하면 을 두 번 번이나 ToList() 또는 ToArray()을 호출하지 않고 계산한다는 것입니다.

7

GetNames()은 두 번 호출되지 않습니다. foreach을 사용하여 컬렉션을 열거 할 때마다 IEnumerable.GetEnumerator()의 구현이 호출됩니다. IEnumerable.GetEnumerator() 값 비싼 계산이 이루어지면 고려해야 할 이유가 될 수 있습니다.