[32] Action, Predicate, Function과 순회 방식을 분리하라

다음 본문은 도서 이펙티브 C# (빌 와그너)에서 나오는 주제를 다룹니다.

 

 

이터레이터 메서드는 크게 두 종류가 있다.

1. 시퀀스 내에서 개별 항목을 이용하여 작업을 수행하는 메서드
2. 시퀀스의 순회 방식을 변경하는 메서드

 

일반적으로 여러 가지 작업을 하나의 메서드에 넣는 이유는 메서드 중간을 커스텀화하기 힘들기 때문이다.

하지만 델리게이트를 사용한다면 메서드 중간을 커스텀 하는 것도 가능하다.

 

하나의 예시로 리스트의 메서드 중 하나인 List<T>.RemoveAll()이 있다.

이 함수는 조건과 일치하는 요소들을 모두 삭제하는데, 이 조건에 Predicate가 사용되었다.

myList.RemoveAll(n => n == 5);

Action<T>를 사용하는 예는 List<T>.ForEach()가 있다.

myList.ForEach(n => Console.WriteLine(n));

 

필터 메서드

필터 메서드는 predicate를 이용하여 작성할 수 있다.

public static IEnumerable<T> Where<T>(IEnumerable<T> sequence, Predicate<T> filterFunc)
{
    if(sequence == null)
        throw new ArgumentNullException(nameof(sequence), "sequence must not be null");
        
    if(filterFunc == null)
        throw new ArgumentNullException("Oreducate must not be null");
    
    foreach(T item in sequence)
        if(filterFunc(item)
            yield return item;
}

 

변환 메서드

변환 메서드는 Func을 통해 작성할 수 있다.

public static IEnumerable<Tout> Select<T in, T out>(IEnumerable<T in> sequence, Func<T in, T out> method)
{
    // 위와 동일하게 null체크는 해야함
    
    foreach(Tin element in sequence)
        yield return method(element);
}

 

결론

 - LINQ가 내부적으로는 이런 느낌으로 구현되어 있구나 하고 알아두면 될 듯하다. 

 

 

댓글

Designed by JB FACTORY