IEnumerable <T>보다 List <T>를 사용해야하는 이유는 무엇입니까? 따르려고합니다. Return IEnumerable(Of Student) vs Return New

내 ASP.net MVC4 웹 응용 프로그램에서 IEnumerables를 사용하여 구현이 아닌 인터페이스로 프로그래밍하기 위해 만트라를 따르려고합니다.

Return IEnumerable(Of Student)

vs

Return New List(Of Student)

사람들은 IEnumerable이 아닌 List를 사용하라고 말하고 있습니다. 목록은 쿼리를 강제로 실행하고 IEumerable은 그렇지 않기 때문입니다.

이것이 가장 좋은 방법입니까? 대안이 있습니까? 인터페이스를 사용할 수있는 콘크리트 물체를 사용하면 이상한 느낌이 듭니다. 이상한 느낌이 정당합니까?



답변

하고있는 경우가 있습니다 ToList()쿼리가 시간에 당신이 그들을 기대하는 순서대로 실행 확인하는 것이 중요 할 수 있습니다 LINQ 쿼리에 있습니다. 그러나 이러한 시나리오는 드물며 진정으로 실행될 때까지 아무도 걱정하지 않아도됩니다.

간단히 말해, IEnumerable반복이 필요할 때만 사용 IList하고 직접 색인을 작성하고 동적 크기의 배열이 필요할 때 사용하십시오 (고정 크기 배열에서 색인을 생성 해야하는 경우 표준 배열을 사용하십시오).

실행 시간의 일에 관해서는, 당신은 항상 같은 목록을 사용할 수 있습니다 IEnumerable그래서를 돌려 주시기 변수 IEnumerable을 수행하여 .ToList();int로서 매개 변수에, 또는 통과 IEnumerable실행하여 .ToList()IEnumerable이 바로 그때 강제로 실행합니다. 강제로 실행을 .ToList()할 때마다 방금 수행 한 IEnumerable변수 에 매달리지 않고 다시 실행하지 않으면 LINQ 쿼리의 반복이 불필요하게 두 배가됩니다.

MVC와 관련하여 여기에 특별히 주목할 것은 없습니다. 그것은 .NET의 나머지 부분과 동일한 실행 시간 규칙을 따를 것입니다. 이전의 지연된 실행 의미로 인해 혼란스러워하는 사람이있을 수 있다고 생각합니다. 아니. 지연된 실행 시맨틱은 처음에는 모든 사람을 혼란스럽게합니다 (그리고 나중에는 좋은 결과를 위해 터치하기 까다로울 수 있습니다). 그러나 LINQ 쿼리가 두 번 실행되지 않거나 다른 코드와 비교하여 특정 순서로 실행되도록 요구 할 때까지 걱정하지 마십시오.이 시점에서 변수를 자신에게 할당하십시오. 강제로 실행하면 괜찮을 것입니다.


답변

두 가지 문제가 있습니다.

IENumerable<Data> query = MyQuery();

//Later
foreach (Data item in query) {
  //Process data
}

“프로세스 데이터”루프에 도달 할 때까지 쿼리가 더 이상 유효하지 않을 수 있습니다. 예를 들어, 이미 Dispose 된 DataContext에서 쿼리를 실행중인 경우 코드에서 예외가 발생합니다. 쿼리를 만든 위치와 다른 컨텍스트에서 쿼리를 처리 할 때 이러한 종류의 문제는 매우 혼란스러워집니다.

두 번째 문제는 “프로세스 데이터”루프가 완료 될 때까지 연결이 해제되지 않는다는 것입니다. “프로세스 데이터”가 복잡한 경우에만 문제가됩니다. 이것은 http://msdn.microsoft.com/en-us/library/bb386929.aspx 에서 언급됩니다 .

Q. 데이터베이스 연결이 얼마 동안 열려 있습니까?

A. 쿼리 결과를 사용할 때까지 연결은 일반적으로 열려 있습니다. 모든 결과를 처리하는 데 시간이 걸리고 결과를 캐싱하는 것이 아니라면 ToList를 쿼리에 적용하십시오. 각 개체가 한 번만 처리되는 일반적인 시나리오에서는 스트리밍 모델이 DataReader와 LINQ to SQL 모두에서 우수합니다.

따라서 이러한 문제 때문에을 호출하여 쿼리가 실제로 실행되도록 권장하고 있습니다 ToList(). 그러나 Jimmy가 제안한 것처럼 List를 IEnumerable로 반환하지 못하게하는 것은 없습니다.

일반적으로 IEnumerable을 두 번 이상 반복하지 않는 것이 좋습니다. 코드 소비자가이 규칙을 준수한다고 가정하면 누군가 쿼리를 두 번 실행하여 데이터베이스에 두 번 충돌 할 우려는 없습니다.


답변

IEnumerable조기 열거의 또 다른 이점은 적절한 위치에서 예외가 발생한다는 것입니다. 이것은 디버깅을 돕습니다.

예를 들어, Razor 뷰 중 하나에 교착 상태 예외가 발생하면 데이터 액세스 방법 중 하나에서 예외가 발생한 것처럼 명확하지 않습니다.


답변