C# 팁: yield return을 사용하여 한 번에 하나의 항목 반환
yield return
는 항상 이해하기 가장 어려운 것 중 하나였습니다.이제 내가 그것을 이해했으므로(완전하지는 않지만 설명하기에 충분함) 이제 내가 배운 것을 공유할 차례입니다.
그렇다면
yield return
는 무엇을 의미합니까? 항목 컬렉션과 어떤 관련이 있습니까?목록 사용
항목 컬렉션을 반환하고 있으며 항목을 반복해야 한다고 가정해 보겠습니다.
첫 번째 접근 방식은 모든 항목이 포함된 목록을 만들어 호출자에게 반환하고 컬렉션을 반복하는 것입니다.
IEnumerable<int> WithList()
{
List<int> items = new List<int>();
for (int i = 0; i < 10; i++)
{
Console.WriteLine($"Added item {i}");
items.Add(i);
}
return items;
}
void Main()
{
var items = WithList();
foreach (var i in items)
{
Console.WriteLine($"This is Mambo number {i}");
}
}
이 스니펫은 전체 컬렉션을 생성한 다음 해당 목록 내의 값을 인쇄합니다. 콘솔에 다음 텍스트가 표시됩니다.
Added item 0
Added item 1
Added item 2
Added item 3
Added item 4
Added item 5
Added item 6
Added item 7
Added item 8
Added item 9
This is Mambo number 0
This is Mambo number 1
This is Mambo number 2
This is Mambo number 3
This is Mambo number 4
This is Mambo number 5
This is Mambo number 6
This is Mambo number 7
This is Mambo number 8
This is Mambo number 9
즉, 100만 개의 항목이 있는 컬렉션에 대해 작업을 수행해야 하는 경우 먼저 모든 항목을 만든 다음 각 항목에 대해 작업을 수행합니다. 이 접근 방식에는 두 가지 주요 단점이 있습니다. 속도가 느리고(특히 해당 항목의 하위 집합으로만 작업해야 하는 경우) 많은 메모리를 차지합니다.
수율로
다른 접근 방식을 사용할 수 있습니다.
yield return
키워드를 사용합니다.IEnumerable<int> WithYield()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine($"Returning item {i}");
yield return i;
}
}
void Main()
{
var items = WithYield();
foreach (var i in items)
{
Console.WriteLine($"This is Mambo number {i}");
}
}
이 방법을 사용하면 메시지 순서가 다릅니다.
Returning item 0
This is Mambo number 0
Returning item 1
This is Mambo number 1
Returning item 2
This is Mambo number 2
Returning item 3
This is Mambo number 3
Returning item 4
This is Mambo number 4
Returning item 5
This is Mambo number 5
Returning item 6
This is Mambo number 6
Returning item 7
This is Mambo number 7
Returning item 8
This is Mambo number 8
Returning item 9
This is Mambo number 9
따라서 전체 목록을 만드는 대신 필요할 때만 한 번에 하나의 항목을 만듭니다.
수율의 이점
이전에 말했듯이
yield
에는 몇 가지 이점이 있습니다. 실행 시간과 메모리 사용량 모두에 대해 이야기할 때 응용 프로그램의 성능이 향상됩니다.자동 반복기와 같습니다. 결과를 얻을 때마다 반복자가 다음 항목으로 이동합니다.
참고:
yield
는 IAsyncEnumerable<T>
, IEnumerable<T>
, IEnumerable
, IEnumerator<T>
또는 IEnumerator
를 반환하는 메서드에서만 작동합니다.예를 들어
List<T>
를 반환하는 메서드와 함께 사용할 수 없습니다.The body of X cannot be an iterator block because
List<int>
is not an iterator interface type
실제 사용 사례
NUnit을 테스트 스위트로 사용한다면 이미 이 키워드를 사용했을 것입니다.
특히
TestCaseSource
속성을 사용할 때 테스트 케이스를 출력하는 클래스의 이름을 지정합니다.public class MyTestClass
{
[TestCaseSource(typeof(DivideCases))]
public void DivideTest(int n, int d, int q)
{
Assert.AreEqual(q, n / d);
}
}
class DivideCases : IEnumerable
{
public IEnumerator GetEnumerator()
{
yield return new object[] { 12, 3, 4 };
yield return new object[] { 12, 2, 6 };
yield return new object[] { 12, 4, 3 };
}
}
테스트를 실행할 때 반복자는 전체 테스트 사례 목록을 만들지 않고 한 번에 테스트 사례를 반환합니다.
이전 스니펫은
TestCaseSource
속성, that you can find here 에 대한 NUnit의 문서에서 직접 가져온 것입니다.마무리
네,
yield
는 상당히 이해하기 어려운 키워드입니다.자세한 내용을 보려면 the official docs으로 이동하십시오.
또 다른 좋은 리소스는 "C# – Use yield return to minimize memory usage" by . 당신은 확실히 그것을 확인해야합니다!
원하는 경우 이 키워드에 대해 나눈 대화를 확인하세요.
즐거운 코딩하세요!
🐧
Reference
이 문제에 관하여(C# 팁: yield return을 사용하여 한 번에 하나의 항목 반환), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/bellonedavide/c-tip-use-yield-return-to-return-one-item-at-the-time-l3텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)