Effective C# 개정판 3판 | 33장 필요한 시점에 필요한 요소를 생성하라.
- C#/Effective C# 책 정리
- 2021. 10. 22. 20:31
1. 참조
- Effective C# 개정판 3판
2. 소개
- Iterator Method 가 입력 변수로 반드시 Sequence 를 받을 필요는 없습니다.
- 작업을 수행하기 전에 필요한 요소를 모두 생성해서 Collection 에 저장해두는 대신 필요할 때마다 개발 요소를 생성하는 식입니다.
- 이 방법으로 코드를 작성하면 사용 되지 않을 요소를 미리 생성하는 것을 피할 수 있습니다.
3.1 정수값의 Sequence 생성
3.2 일반 Collection 예제 코드
using System;
using System.Collections.Generic;
namespace Chapter33
{
class Program
{
static void Main(string[] args)
{
var result = CreateSequence(5, 1, 0);
foreach (var item in result)
{
Console.WriteLine($"value : {item}");
}
}
static IList<int> CreateSequence(int numberOfElements, int startAt, int stepBy)
{
var collection = new List<int>(numberOfElements);
for(int idx =0; idx < numberOfElements; idx++)
{
collection.Add(startAt + idx + stepBy);
}
return collection;
}
}
}
3.3 실행 결과
value : 1
value : 2
value : 3
value : 4
value : 5
- 위의 코드는 잘 동작하지만 yield return 을 이용하여 새로운 시퀀스를 생성하는 것에 비하여 단점이 많습니다.
- 우선 위의 코드는 결과를
List<int>
에 저장한다고 가정하고 있습니다. - 클라이언트가
BindingList<int>
와 같이 다른 타입을 요구하면 변환 작업을 반드시 수행해야 합니다. - 이처럼 변환을 수행하면 그 과정에서 미묘한 버그가 발생할 소지가 있습니다.
- 또한, 클라이언트가 중간에 작업을 중단할 수 없기 떄문에
CreateSequence()
메서드는 항상 요청된 개수 만큼 요소를 생성합니다. - Sequence를 생성하는 기능을 Iterator Method로 만들면 위와 같은 문제들을 피할 수 있습니다.
3.4 yield return 이용한 예제 코드
using System;
using System.Collections.Generic;
namespace Chapter33
{
class Program
{
static void Main(string[] args)
{
var result = CreateSequence(5, 1, 0);
foreach (var item in result)
{
Console.WriteLine($"Value : {item}");
}
}
static IEnumerable<int> CreateSequence(int numberofElements, int startAt, int stepBy)
{
for(int idx = 0; idx < numberofElements; idx++)
{
yield return startAt + idx + stepBy;
}
}
}
}
3.5 실행 결과
value : 1
value : 2
value : 3
value : 4
value : 5
- 위와 같이 새로게 작성한 코드를 실행하면 Sequence 내의 개별 요소가 요청 시마다 하나씩 생성됩니다.
- 동일한 int 타입의 요소를 생성하기 때문에 코드를 위처럼 수정해도 작업의 내용은 변경되지 않습니다.
- 그리고 이 코드는 어떤 Collection에 저장하더라도 문제없이 동작합니다.
- 또한, 조건에 부합하지 않는 상황이 됐을 때 추가로 숫자를 생성하지 않으므로 2.2 예제 코드에 비해서 성능상의 이점이 있습니다.
4. 정리
- Sequence를 소비하는 측에서 값을 요청하는 시점에 맞춰 필요한 값을 생성하는 것이 가장 좋습니다.
- Sequence 전체를 소비하지 않고 일부만 필요한 경우임에도 전체 요소를 미리 생성해 두는 것은 좋은 방법이 아닙니다.
- 어떤 경우라도 필요한 시점에 맞춰 필요한 요소를 생성하도록 코딩하는 것이 가장 효과적입니다.
yield return
구문을 자주 사용하길 권장합니다.
728x90
'C# > Effective C# 책 정리' 카테고리의 다른 글
[C#] Effective C# 9장. 박싱과 언박싱을 최소화하라. (0) | 2023.02.23 |
---|---|
[Effective C#] 45. 메서드가 실패했음을 알리기 위해서 예외를 이용하라 (0) | 2021.11.30 |
Effective C# 개정판 3판 | 29장 Collection 을 반환하기보다 Iterator 를 반환하는 것이 낫다. (0) | 2021.10.12 |
[Effective C# 개정판 3판] Item : 27장 인터페이스는 간략히 정의하고 기능의 확장은 확장 메서드를 사용하라 (0) | 2021.08.15 |
[Effective C# 개정판 3판] 아이템 25: 타입 매개변수로 인스턴스 필드를 만들 필요가 없다면 제네릭 메서드를 정의하라 (0) | 2021.08.11 |
이 글을 공유하기