구현을 숨기는 것은 OOP의 핵심 원칙이며 모든 패러다임에서 좋은 아이디어이지만 지연 반복을 지원하는 언어에서 반복자 (또는 특정 언어로 불려지는 것)에 특히 중요합니다.
구체적인 유형의 이터 러블 또는 심지어 인터페이스와 같은 노출 유형의 문제 IList<T>
는 그것들을 노출시키는 객체가 아니라 그것을 사용하는 방법에 있습니다. 예를 들어 Foo
s 목록을 인쇄하는 기능이 있다고 가정 해 봅시다 .
void PrintFoos(IList<Foo> foos)
{
foreach (foo in foos)
{
Console.WriteLine(foo);
}
}
해당 함수를 사용하여 foo 목록을 인쇄 할 수 있습니다. IList<Foo>
IList<Foo> foos = //.....
PrintFoos(foos);
그러나 목록의 짝수 색인 항목을 모두 인쇄하려면 어떻게해야 합니까? 새 목록을 만들어야합니다.
IList<Foo> everySecondFoo = new List<T>();
bool isIndexEven = true;
foreach (foo; foos)
{
if (isIndexEven)
{
everySecondFoo.Add(foo);
}
isIndexEven = !isIndexEven;
}
PrintFoos(everySecondFoo);
이것은 꽤 길지만 LINQ를 사용하면 하나의 라이너로 할 수 있습니다. 실제로 더 읽기 쉽습니다.
PrintFoos(foos.Where((foo, i) => i % 2 == 0).ToList());
자, 당신 .ToList()
은 결국을 알았 습니까? 이렇게하면 게으른 쿼리가 목록으로 변환되므로에 전달할 수 있습니다 PrintFoos
. 이를 위해서는 두 번째 목록이 할당되고 두 번째 항목이 항목에 전달됩니다 (하나는 첫 번째 목록에 하나는 두 번째 목록을 작성하고 다른 하나는 두 번째 목록에 인쇄). 또한 우리가 이것을 가지고 있다면 :
void Print6Foos(IList<Foo> foos)
{
int counter = 0;
foreach (foo in foos)
{
Console.WriteLine(foo);
++ counter;
if (6 < counter)
{
return;
}
}
}
// ........
Print6Foos(foos.Where((foo, i) => i % 2 == 0).ToList());
foos
수천 개의 항목이 있으면 어떻게 됩니까? 우리는 그것들을 모두 살펴보고 6 장만 인쇄하기 위해 거대한 목록을 할당해야합니다!
열거 자-C #의 반복자 패턴 버전을 입력하십시오. 우리의 함수가리스트를 받도록하는 대신, 우리는 그것을 받아들입니다 Enumerable
:
void Print6Foos(Enumerable<Foo> foos)
{
// everything else stays the same
}
// ........
Print6Foos(foos.Where((foo, i) => i % 2 == 0));
이제 Print6Foos
목록의 처음 6 개 항목을 느리게 반복 할 수 있으며 나머지 항목은 건드릴 필요가 없습니다.
내부 표현을 공개하지 않는 것이 여기의 핵심입니다. 때 Print6Foos
그 지원 랜덤 액세스 뭔가 - - 목록을 받아, 우리는 그것에게 목록을 제공했고 서명이 보장되지 않기 때문에, 따라서 우리는 목록을 할당해야한다고 그것을 통해서만으로 반복됩니다. 구현을 숨기면 Enumerable
함수가 실제로 필요한 것만 지원 하는보다 효율적인 객체를 쉽게 만들 수 있습니다 .