C# yield 이해하기
yield는 iterator를 포함하는 메서드에서 사용되는 강력한 키워드이다. yield를 사용하면 enumerable 배열을 간단하게 반환할 수 있다. 하나의 요소를 해당 시점에서 반환하기 때문에 기존의 전통적인 반환 방법과는 다르다.
- 지연 평가(lazy evaluation)
- 성능 향상(increased perforamance)
- 대량의 데이터, 복잡한 데이터 구조를 다루는데 효과적
- iteration 간의 상태 지속이 가능
기본 구문
public IEnumerable<int> GetNumbers()
{
for (int i = 0; i < 10; i++)
{
yield return i;
}
}
위의 예에서, GetNumbers()는 0에서 9까지의 정수 시퀀스를 생성한다. yield return을 사용하여 다음 숫자를 생성한다.
시나리오 1 : 지연 로딩 (Lazy Loading)
거대한 크기의 데이터셋을 다룬다고 상상해 보자. 수백만 줄의 파일이라고 생각하면 좋을 거 같다. 전체 데이터셋을 전부 메모리에 올리면 이는 매우 비효율적이고 자원-집약적이다.
public IEnumerable<string> ReadLargeFile(string filePath)
{
using (var file = new StreamReader(filePath))
{
string line;
while ((line = file.ReadLine()) != null)
{
yield return line;
}
}
}
해당 메서드는 파일을 한줄씩 읽는다. 읽은 각 라인을 리턴한다. 이러한 방식은 메모리 효율적이고 한 라인에 대한 메모리만을 필요로 한다.
시나리오 2 : 복잡한 비지니스 로직 (Complex Business Logic)
yield를 이용하면 복잡한 비지니스 로직을 기반으로 하는 컬렉션의 필터링을 명확하고 효율적으로 만들 수 있다.
public IEnumerable<Product> FilterProducts(
IEnumerable<Product> products, Criteria criteria
)
{
foreach (var product in products)
{
if (MeetsCriteria(product, criteria))
{
yield return product;
}
}
}
특정한 조건을 충족하는 경우에만 product를 반환합니다. 이는 복잡한 로직을 단순화하고 코드의 가독성을 향상된다.
시나리오 3 : 무한 시퀀스 (Infinite Sequences)
yield를 사용하면 무한 시퀀스를 쉽게 구현할 수 있다. 끝없는 데이터의 흐름을 생성하는 시나리오를 생각해 보자.
public IEnumerable<int> GenerateInfiniteSequence()
{
int i = 0;
while (true)
{
yield return i++;
}
}
위의 매소드는 끝없는 정수의 배열을 생성한다. 이러한 접근은 시뮬레이션이나 데이터 애플리케이션 스트리밍에서 유용할 것이다.
시나리오 4 : 상태 반복자 (Statful Iterations)
yield는 반복 사이에서 상태를 유지한다. 이 기능은 상태 머신과 같이 각 반복의 상태가 중요한 시나리오에 활용이 가능하다.
public IEnumerable<State> RunStateMachine(State initialState)
{
State currentState = initialState;
while (currentState != null)
{
yield return currentState;
currentState = currentState.NextState();
}
}
정리하자면
C#에서 yield 키워드는 가능성이 무궁무진하다. 올바르게 사용한다면, 코드의 효율과 가독성을 획기적으로 향상할 수 있다. 특히 대량의 데이터 셋을 다루는 경우, 복잡한 로직, 무한 배열, 그리고 상태 반복자에 대해서 유용하게 사용이 가능하다. yield에 대해서 익숙해지면, 면접에서 깊은 인상을 남길 수 있을 뿐만 아니라 실제 프로그래밍 과제를 해결하는데 매우 유용한 고급 기술을 갖추게 될 것이다.
출처
'프로그래밍 > C#' 카테고리의 다른 글
C# Value Type vs Reference Type (0) | 2024.02.15 |
---|---|
C# yield return을 이용한 소수 생성기 (1) | 2024.02.14 |
C# 지연 평가(lazy evaluation)에 대해서 (0) | 2024.02.13 |
C# Virtual vs Abstract (0) | 2024.02.03 |
C# 변수 캡처(Capture)에 대해서 (1) | 2024.01.23 |
댓글