무한한 양의 항목을 (이론적으로) 반환하는 열거자를 어떻게 설계합니까?

StackOverflow https://stackoverflow.com/questions/197297

  •  10-07-2019
  •  | 
  •  

문제

나는 이것과 비슷한 것처럼 보이는 코드를 작성하고 있습니다.

public IEnumerable<T> Unfold<T>(this T seed)
{
    while (true)
    {
        yield return [next (T)object in custom sequence];
    }
}

분명히,이 방법은 결코 돌아 오지 않을 것입니다. (C# 컴파일러는 조용히 허용하지만 r#은 경고를 제공합니다. "기능이 반환되지 않는다".)

일반적으로 말하자면입니다 나쁜 열거를 중지하는 방법을 제공하지 않고 무한한 수의 품목을 반환하는 열거자를 제공하는 디자인?

이 시나리오에 대한 특별한 고려 사항이 있습니까? 씨? 성만 해요? 다른 gotchas?

우리가 항상 출구 조건을 제공한다면 옵션은 무엇입니까? 예 :

  • 포용 적 또는 독점 경계를 나타내는 T 형 객체
  • Predicate<T> continue (처럼 TakeWhile 하다)
  • 카운트 (AS Take 하다)
  • ...

사용자에게 전화를 걸어야합니다 Take(...) / TakeWhile(...) ~ 후에 Unfold(...)? (기존 LINQ 지식을 활용하기 때문에 선호하는 옵션 일 수도 있습니다.)

코드가 공개 API (genic) 또는이 패턴의 특정 구현으로 공개 API에 게시 될 경우이 질문에 다르게 대답 하시겠습니까?

도움이 되었습니까?

해결책

메소드가 반복을 끝내지 않을 것이라고 매우 명확하게 문서화하는 한 (메소드 자체가 매우 빨리 돌아옵니다) 괜찮다고 생각합니다. 실제로 일부 알고리즘을 훨씬 깔끔하게 만들 수 있습니다. 반복자 내에서 "비싼"객체를 참조하면 그 참조가 캡처 될 것입니다.

API를 남용하는 방법은 항상 있습니다. 문서가 명확 해지면 괜찮다고 생각합니다.

다른 팁

"일반적으로, 열거를 중지 할 수있는 방법을 제공하지 않고 무한한 양의 품목을 반환하는 열거자를 제공하는 것은 나쁜 소식입니까?"

코드의 소비자는 할 수 있습니다 언제나 열거 중지 (예 : 브레이크 또는 기타 수단 사용). 열거자가 반환하고 무한한 시퀀스를 사용하는 경우, 열거 자의 클라이언트가 어떻게 열거를 깨뜨리지 말아야한다는 것을 의미하지는 않습니다. 실제로 고객이 완전히 열거 된 열거자를 만들 수는 없습니다.

펼쳐진 후 Take (...) / Take (...)를 호출하는 사용자에게 의존해야합니까 (...)? (기존 LINQ 지식을 활용하기 때문에 선호하는 옵션 일 수도 있습니다.)

예, 귀하의 문서에서 열거자가 반환하고 무한한 시퀀스와 열거의 파괴가 발신자의 책임이라는 문서를 명확하게 지정하는 한, 모든 것이 정상이어야합니다.

무한한 시퀀스를 반환하는 것은 나쁜 생각이 아니며, 기능적 프로그래밍 언어는 오랫동안 해냈습니다.

나는 Jon에 동의합니다. 컴파일러는 메소드를 클래스로 변환하여 현재 값 (즉, 현재 속성을 통해 반환 될 값)을 참조하는 간단한 상태 머신을 구현합니다. 이 접근법을 여러 번 사용하여 코드를 단순화했습니다. 방법의 동작을 명확하게 문서화하면 잘 작동해야합니다.

나는 공개 API에서 무한 열거자를 사용하지 않을 것입니다. C# 프로그래머는 나 자신이 포함 된 Foreach 루프에 너무 익숙합니다. 이것은 또한 .NET 프레임 워크와 일치합니다. 열거 가능한 방법에 주목하십시오. Range and Enumerable.repeat 메소드는 열거 가능한 항목의 수를 제한하기 위해 인수를받습니다. Microsoft는 enumerable.repeat ( "", 10)을 열거 가능한 repeat ( "") 대신 사용하기로 결정했습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top