2010-07-05 6 views
35

메소드에서 정렬 된 항목 목록을 반환하고 싶습니다. 내 반환 형식 IEnumerable 또는 IList 수해야합니까?IEnumerable 또는 IList를 반환해야합니까?

+0

나는 아직 답을 확신 할 수 없다. 현재의 사고 - 모든 IEnumerable의 요소 보증 순서가 아니므로 IList에 기대고 있습니다. – Ben

+1

벤, 어떻게 작동하지 않습니다. 당신은 이미 어떤 것을 주문했는데 (List), IEnumerable로 노출시킨다. 해당 인터페이스는 주문을 변경할 수 없습니다 (변경할 수 없음). 수신하는쪽에 필요한 것을 살펴보고 가장 작은 옵션을 선택하십시오. –

+0

@Henk - 감사합니다. 인터페이스에 메서드가 있고 결과 값이 정렬되지 않는다면 IList 또는 유사하게 제안 할 것입니까? – Ben

답변

37

여기에 계층 구조가 있습니다 :

interface IList<T> : ICollection<T> { } 
interface ICollection<T> : IEnumerable<T> { } 

당신은 최소한의 커플 링을 목표로, 그래서 충분 경우 IEnumerable<T>을 반환하려면이. 그것은 아마있을 것입니다.

발신자가 추가/삽입/제거에 사용할 수있는 목록을 가져야하는 상황이 발생하면 IList<T>을 반환하십시오. 그러나 호출자가 IEnumerable 컬렉션에서 자신의 List를 만든 경우에도 더 좋을 수 있습니다.

+3

IEnumerable을 사용할 때 ElementAt 및 Count 함수는 어떻게됩니까? ElementAt를 호출 할 때마다 반복문은 요소를 찾을 때까지 전체 목록을 통과합니다. 이것은 전체 목록에서 루프를 제외하고 Count를 사용하는 동일한 동작입니다. 이것은 추가, 제거 및 삽입 외에 목록을 사용하는 데 고려해야합니다. 내가 잘못? – Samuel

+0

죄송 합니다만 가능한 커플 링을 확장 할 수 있습니까? IList 이 IEnumerable 이고 Count와 같은 장점이있는 경우 색인을 생성하면 왜 반환하지 않겠습니까? – Kakira

+0

생산 끝에서 IEnumerable 만 반환하면 나중에 다른 라이터 구현을 선택하게됩니다. 소비가 끝나면 더 중요합니다. –

2

IEnumerable은 IList보다 덜 구체적입니다. 즉, IList에는 IEnumerable에서 제공하지 않는 함수가 있습니다.

두 기능을 비교하여 다른 기능이 필요없는 기능이 있는지 확인하십시오.

3

정렬 된 목록을 반환하려면 SortedList를 반환해야합니다.

http://msdn.microsoft.com/en-us/library/system.collections.sortedlist.aspx

당신은 개체와 주문을 연결할 수 있습니다.

+0

대답처럼 보입니다 ... – Ben

+1

.NET 컬렉션이 주문을 보증하는 정보를 알려주는 정보를 가르쳐 주시겠습니까? – Ben

+0

사실, 정렬 된 목록은 형식에 따라 결과가 정렬됩니다. 그러나 그것을 조작 할 수 있습니다. 이것이 의도하지 않는다면, 나는 ienumerable과 함께 가고, 설명에 정렬을 문서화한다. – cRichter

2

IList에는 항목 (예 : 추가)을 변경하는 방법이 있습니다. ICollection과 IEnumerable 사이에서 선택하려고 할 수 있습니다.

ICollection은 IEnumerable을 확장하고 유용 할 Count 속성을 사용할 수 있습니다.

5

간편한 발신자가 Readonly 만 사용해야하는 경우에는 IEnumerable을 사용하십시오. 이것은 공분산 (결과는 기본 유형으로 변환 될 수 있습니다)을 지원합니다.

+2

그것은 사실 공변이지만 중요한 점입니다. –

+0

재미있는 포인트 공분산 – Ben

+1

IOBeredableEnumerable 인터페이스는 OrderBy Enumerable 확장 메소드에 의해 반환됩니다. 읽기 전용입니다. –

4

일반적으로 발신자에게 필요한 모든 것이있는 한 IEnumerable<T>을 반환하는 것이 좋습니다.

IEnumerable<T>은 foreachable이며 많은 소비자에게 필요한 전부입니다. 읽기 전용이기도합니다. 이는 흔히 당신에게 말하지 않고 누군가를 수정하는 것에 대해 너무 걱정하지 않고 실제 백업 컬렉션을 반환하여 최적화 할 수 있음을 의미합니다.

그러나 소비자가 IEnumerable<T>에없는 방법을 필요로하면 IList<T>이 더 적합 할 수 있습니다. 예를 들어 발신자는 Contains으로 전화 할 수도 있습니다.이 번호는 IEnumerable<T>이 아닙니다. 또는 호출자가 처음부터 끝까지 반복하지 않고 목록에 색인을 생성 할 수 있습니다.

하지만 LINQ의 ContainsElementAt 확장 방법을 통해 IEnumerable<T>에도 포함 및 색인 생성을 수행 할 수 있습니다. 여기서 학위 문제가 있습니다. 발신자가 IEnumerable<T>에서 사용할 수없는 질문 하나 (예 : "is this empty")를 묻는 경우 IEnumerable<T>을 반환하고 Any 확장 방법을 사용합니다. 그러나 발신자가 IList<T> 작업을 광범위하게 사용하는 경우 IList<T>을 반환하십시오.

+0

LINQ 버전의 Contains 및 ElementAt를 사용하면 성능 문제가 발생할 수 있으므로 foreach를 발생시키는 후드에서 발생하므로 항상 O (n)이됩니다. IList Contains 또는 ElementAt의 구현에 따라 O (1) 연산이 될 수 있습니다. – Oliver

+4

@ 올리버, "항상"이라고 말하는 것은 잘못입니다. LINQ Contains와 ElementAt는 컬렉션을'ICollection '/'IList '으로 캐스팅하려고 시도하므로 O (1) 메서드를 호출 할 수 있습니다. O (n) 구현은 실패 할 경우에만 사용됩니다. 'List '을'IEnumerable '이라고 입력하면 Contains와 ElementAt는 약간의 추가 오버 헤드가 있지만 여전히 O (1)입니다. 반사경에서 이것을 확인할 수 있습니다. –

+0

정보를 제공해 주셔서 감사 드리며, 아직 배워야 할 새로운 내용이 있습니다. ;-) – Oliver

12

결과에 따라 원하는 결과가 결정됩니다. 항목 수를 얻거나 개별 항목에 임의로 액세스해야하는 경우 IList로 이동하십시오.

발신자가 바로 항목을 반복 할 경우는 IEnumerable과 함께 할 것입니다 - 을하지만 반환 값이 느리게 여부를 평가할지 여부를 문서화해야합니다 - 많은 IEnumerable을 경우 이러한 일이 실행됩니다 쿼리를 나타낼 때 컬렉션이 열거됩니다. 당신이 돌아 오는 것이 수요에 따라 평가되지 않는다면, 나는 IList와 함께 갈 것입니다.

+0

+1 문서 강조. –

+0

+1 첫 문장. 이 답변을 읽기 전에 아래에 의견을 적었습니다. – Samuel

관련 문제