2016-12-21 6 views
7

은 내 질문이 IReadOnlyCollection<T>IEnumerable<T>의 사용에 관한 this one 관련이되지 않도록하는 IReadOnlyCollection 대신 IEnumerable을 사용. 매개 변수를 가능한 여러 열거

나는 항상 IEnumerable<T>을 사용하여 반환 유형과 매개 변수 모두로 컬렉션을 노출합니다.이 컬렉션은 변경 불가능하고 느리게 실행되는 이점이 있기 때문입니다.

그러나 ReSharper가 제공하는 가능한 다중 열거 경고를 피하기 위해 매개 변수를 열거해야하는 곳에서 코드의 위치가 확산되는 것에 대해 점점 더 우려하고 있습니다. 나는 ReSharper가 이것을 제안하는 이유를 이해하며 캡슐화를 보장하기 위해 (아래에서) 제안하는 코드에 동의합니다 (즉 발신자에 대한 가정 없음).

Foo[] arr = col as Foo[] ?? col.ToArray(); 

는 그러나, 나는 그리고 오염이 코드의 반복성을 발견하고 나는 IReadOnlyCollection<T>이 상태 특히 포인트 this article에서 만든 더 나은 대안이라고 일부 소스에 동의 :

을 최근에, I 반환의 장점과 단점을 고려 해왔다. IEnumerable<T>.

더하기 측면에서

, 인터페이스가수록 그것에 대해 같은 최소한의, 그래서 방법의 저자로 IList<T> 또는 (heaven forbid) 배열과 같은 무거운 대안에 투입보다 더 많은 유연성을 떠난다. 내가 the last post에 설명 된대로

그러나, IEnumerable<T> 반환 는 Liskov Substitution Principle을 위반하는 호출자를 유혹한다. Last()Count()과 같은 LINQ 확장 메서드를 사용하기 쉽고, 의미가 IEnumerable<T> 인 것은 아닙니다.

반환 된 컬렉션 의 유혹을 그렇게 눈에 띄지 않게 잠그는 것이 좋습니다. (Barney를 생각 나게합니다 Fife는이 수업을 어렵게 배웁니다.)

IReadOnlyCollection<T>을 .Net 4.5에 새로 추가하십시오. IEnumerable<T>에 속성 하나만 추가하면 Count 속성이 추가됩니다. 카운트를 약속하면 귀하의 발신자에게 IEnumerable<T>에는 실제로 개의 단말이 있음을 보증합니다. 그런 다음 Last()과 같은 LINQ 확장 메서드를 사용하여 명확한 양심을 사용할 수 있습니다.

그러나 주목할만한 것처럼이 기사에서는 반환 유형으로 IReadOnlyCollection<T>을 사용하는 방법에 대해서만 설명합니다. 제 질문은 매개 변수에도 똑같이 적용할까요? 이것에 대한 이론적 인 생각이나 의견도 환영 할 만하다.

실제로 IReadOnlyCollection<T>을 사용하는 일반적인 경험 규칙은 IEnumerable<T>을 사용하는 경우 여러 열거 형 (ReSharper 경고와 함께)이 가능할 것이라고 생각합니다. 그렇지 않으면 IEnumerable<T>을 사용하십시오.

+0

Resharper의 주석에 '[NoEnumeration]'이라는 속성이 있습니다 만 그 속성은 잘 알려져 있지만'매개 변수로 전달 된 IEnumerable이 열거되지 않음을 나타냅니다 .'라고 말하면서 아무것도 사용하지 않습니다. –

+0

@ M.kazemAkhgary, 멋지다. 유용하다. IEnumerable을 어디에서 열거하고 있지 않은지 추측 할 수있다. 하지만 내 질문은 그 유스 케이스보다 더 넓고,'IEnumerable' *이 열거 된 곳이 더 많다. 이 경우 'IReadOnlyCollection '이 내가 언급 한 이유 (즉, 기사에서 지적한 점) 때문에 더 나은 대안일까요? – Neo

답변

1

이것에 대해 더 생각해 본 결과, IReadOnlyCollection<T>을 매개 변수로 사용하는 것이 맞지만 실제로 열거 될 함수에서만 사용할 수 있다고 결론을 내 렸습니다. 열거 형이 다른 매개 변수, 개체 상태 또는 워크 플로를 기반으로 조건부 일 경우 지연 계산이 의미 론적으로 보장되도록 IEnumerable<T>으로 전달해야합니다.