문제

나는 그것이 무엇 인줄 안다 yield 몇 가지 예를 보았지만 실제 적용 사례가 생각나지 않습니다. 특정 문제를 해결하기 위해 이를 사용한 적이 있습니까?

(이상적으로는 다른 방법으로 해결할 수 없는 문제)

도움이 되었습니까?

해결책

나는 이것이 오래된 질문이라는 것을 알고 있습니다(Jon Skeet 이전?). 그러나 나는 최근에 이 질문을 스스로 생각해 왔습니다.불행하게도 여기에 있는 현재 답변(제 생각에는)은 항복 설명의 가장 분명한 이점을 언급하지 않습니다.

Yield 문의 가장 큰 이점은 표준 목록을 사용하는 것보다 훨씬 더 효율적인 메모리 사용으로 매우 큰 목록을 반복할 수 있다는 것입니다.

예를 들어, 100만 개의 행을 반환하는 데이터베이스 쿼리가 있다고 가정해 보겠습니다.DataReader를 사용하여 모든 행을 검색하고 이를 List에 저장할 수 있으므로 list_size * row_size 바이트의 메모리가 필요합니다.

또는 Yield 문을 사용하여 Iterator를 생성하고 한 번에 하나의 행만 메모리에 저장할 수 있습니다.실제로 이는 대규모 데이터 세트에 대해 "스트리밍" 기능을 제공하는 기능을 제공합니다.

또한 Iterator를 사용하는 코드에서는 간단한 foreach 루프를 사용하고 필요에 따라 루프에서 벗어나도록 결정할 수 있습니다.일찍 중단하면(예를 들어) 처음 5개 행만 필요할 때 전체 데이터 세트를 강제로 검색하지 않은 것입니다.

에 관하여:

Ideally some problem that cannot be solved some other way

Yield 문은 사용자 정의 반복기 구현을 사용하여 수행할 수 없는 작업을 제공하지 않지만 필요한 복잡한 코드를 작성할 필요가 없도록 해줍니다.여러 가지 방법으로 해결할 수 없는 문제는 거의 없습니다.

다음은 더 자세한 내용을 제공하는 몇 가지 최근 질문과 답변입니다.

수익 키워드 가치가 추가되었나요?

LINQ 외부에서 수익률이 유용합니까?

다른 팁

실제로 내 사이트에서는 비전통적인 방식으로 사용합니다. 아이디어파이프

public override IEnumerator<T> GetEnumerator()
{
    // goes through the collection and only returns the ones that are visible for the current user
    // this is done at this level instead of the display level so that ideas do not bleed through
    // on services
    foreach (T idea in InternalCollection)
        if (idea.IsViewingAuthorized)
            yield return idea;
}

따라서 기본적으로 아이디어 보기가 현재 승인되었는지 확인하고 승인된 경우 아이디어를 반환합니다.그렇지 않은 경우에는 그냥 건너뜁니다.이를 통해 아이디어를 캐시할 수 있지만 승인된 사용자에게 아이디어를 계속 표시할 수 있습니다.그렇지 않으면 1시간마다 순위가 다시 매겨지는 경우 권한에 따라 매번 다시 가져와야 합니다.

한 가지 흥미로운 용도는 특히 여러 단계를 수행하고 각 단계에서 동일한 데이터 세트가 필요한 작업에 대한 비동기 프로그래밍 메커니즘으로 사용되는 것입니다.이에 대한 두 가지 예는 Jeffery Richters AysncEnumerator입니다. 1 부 그리고 2 부.동시성 및 조정 런타임(CCR)도 이 기술을 사용합니다. CCR 반복자.

Enumerable 클래스의 LINQ 연산자는 항복 문을 사용하여 생성된 반복기로 구현됩니다.일반적으로 루프에서 열거자를 사용할 때까지 실제로 아무것도 열거하지 않고 Select() 및 Where()와 같은 작업을 연결할 수 있습니다. 각각 성명.또한 컬렉션 중간에 중지하기로 결정한 경우 IEnumerator.MoveNext()를 호출하면 하나의 값만 계산되므로 모든 결과 계산에 따른 성능 저하를 줄일 수 있습니다.

반복자는 필요할 때만 표현식이 평가되는 다른 종류의 지연 평가를 구현하는 데에도 사용할 수 있습니다.당신은 또한 사용할 수 있습니다 생산하다 코루틴과 같은 더 멋진 것들을 위해.

Yield의 또 다른 좋은 용도는 IEnumerable의 요소에 대해 함수를 수행하고 다른 유형의 결과를 반환하는 것입니다. 예를 들면 다음과 같습니다.

public delegate T SomeDelegate(K obj);

public IEnumerable<T> DoActionOnList(IEnumerable<K> list, SomeDelegate action)
{
    foreach (var i in list)
        yield return action(i);
}

Yield를 사용하면 구체적인 유형으로 다운캐스팅되는 것을 방지할 수 있습니다.이는 컬렉션 소비자가 컬렉션을 조작하지 못하도록 하는 데 유용합니다.

당신은 또한 사용할 수 있습니다 yield return 일련의 함수 결과를 목록으로 처리합니다.예를 들어 직원들에게 2주마다 급여를 지급하는 회사를 생각해 보세요.다음 코드를 사용하면 급여 날짜의 하위 집합을 목록으로 검색할 수 있습니다.

void Main()
{
    var StartDate = DateTime.Parse("01/01/2013");
    var EndDate = DateTime.Parse("06/30/2013");
    foreach (var d in GetPayrollDates(StartDate, EndDate)) {
        Console.WriteLine(d);
    }
}

// Calculate payroll dates in the given range.
// Assumes the first date given is a payroll date.
IEnumerable<DateTime> GetPayrollDates(DateTime startDate, DateTime endDate, int     daysInPeriod = 14) {
    var thisDate = startDate;
    while (thisDate < endDate) {
        yield return thisDate;
        thisDate = thisDate.AddDays(daysInPeriod);
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top