티스토리 뷰
이터레이터 메서드가 입력 변수로 반드시 시퀀스를 받을 필요는 없다. 이터레이터 메서드를 구현할 때 새로운 시퀀스를 출력하기 위해 yield return을 자주 사용하는데 이 과정에서 입력 시퀀스를 활용하는 대신 새로운 팩토리 메서드를 이용할 수도 있다.
작업을 수행하기 전에 필요한 요소를 모두 생성해서 컬렉션에 저장해두는 대신 필요할 때마다 개발 요소를 생성하는 식이다. 이 방법으로 코드를 작성하면 사용 되지 않을 요소를 미리 생성하는 것을 피할 수 있다.
예시 1) 정숫값의 시퀀스 생성
이 코드는 잘 동작하지만 yield return을 이용하여 새로운 시퀀스를 생성하는 것에 비해서는 단점이 많다.
우선 이 코드는 결과를 List<int>에 저장한다고 가정하고 있다. 클라이언트가 BindingList<int>와 같이 다른 타입을 요구하면 변환 작업을 반드시 수행해야 한다. 이처럼 변환을 수행하면 그 과정에서 미묘한 버그가 발생할 소지가 있다.
또한 클라이언트가 중간에 작업을 중단할 수 없기 때문에 CreateSequence() 메서드는 항상 요청된 개수만큼 요소를 생성한다.
시퀀스를 생성하는 기능을 이터레이터 메서드로 만들면 이 같은 문제들을 모두 피할 수 있다.
새롭게 작성한 코드를 실행하면 시퀀스 내의 개별 요소가 요청 시마다 하나씩 생성된다. 동일한 int 타입의 요소를 생성하기 때문에 코드를 이처럼 수정해도 작업의 내용이 변경되지는 않는다. 그리고 이 코드는 어떤 컬렉션에 저장하더라도 문제없이 동작한다. 그리고 조건에 부합하지 않는 상황이 됐을 때 추가로 숫자를 생성하지 않으므로 성능상에 이점이 있다.
결론
시퀀스를 소비하는 측에서 값을 요청하는 시점에 맞춰 필요한 값을 생성하는 것이 가장 좋다. 시퀀스 전체를 소비하지 않고 일부만 필요한 경우임에도 전체 요소를 미리 생성해두는 것은 좋은 방법이 아니다.
어떤 경우라도 필요한 시점에 맞춰 필요한 요소를 생성하도록 코딩하는 것이 가장 효과적이다.
참조 - Effective C# <강력한 C# 코드를 구현하는 50가지 전략과 기법, 이펙티브>, 빌 와그너, 김명신, 한빛미디어
'Programming > Effective C#' 카테고리의 다른 글
[Effective C# Item 35] 확장 메서드는 절대 오버로드하지 마라 (0) | 2020.10.20 |
---|---|
[Effective C# Item 34] 함수를 매개변수로 사용하여 결합도를 낮추라 (0) | 2020.10.20 |
[Effective C# Item 32] Action, Predicate, Function과 순회 방식을 분리하라 (0) | 2020.10.20 |
[Effective C# Item 30] 루프보다 쿼리 구문이 낫다 (0) | 2020.10.20 |
[Effective C# Item 29] 컬렉션을 반환하기보다 이터레이터를 반환하는 것이 낫다 (0) | 2020.10.18 |