개발공부/C#

[Effective C#] 아이템 38 : 메서드보다 람다 표현식이 낫다.

개발자 찐빵이 2021. 12. 13. 22:19
728x90

람다 표현식과 메서드 비교

var allEmployees = FindAllEmployees();

// 20년 이상 근속자
var earlyFolks = from e in allEmployees
                    where e.Classification == EmployeeType.Salary
                    where e.YearsOfService >= 20
                    where e.MonthlySalary < 4000
                    select e;
// 20년 미만 근속자
var newest = from e in allEmployees
                where e.Classification == EmployeeType.Salary
                where e.YearsOfService < 20
                where e.MonthlySalary < 4000
                select e;

람다 표현식의 단점

  • 동일한 코드를 반복하는 경우가 발생한다.

코드의 반복을 방지하기 위해 재사용 가능한 메서드를 사용할 수 있다.

//메서드로 분리
private static bool LowPaidSalaried(Employee e) =>
    e.MonthlySalary < 4000 && e.Classification ==
    EmployeeType.Salary;

var allEmployees = FindAllEmployees();

// 20년 이상 근속자
var earlyFolks = from e in allEmployees
                    where LowPaidSalaried(e) && e.YearsOfService >= 20
                    select e;
// 20년 미만 근속자
var newest = from e in allEmployees
                where LowPaidSalaried(e) && e.YearsOfService < 20
                select e;

하지만 메서드로 분리한 부분은 재사용 가능성이 낮다.
첫 번째 코드가 람다 표현식이 평가되고, 파싱 되고, 수행되는 일련의 과정 때문에 재사용 가능성이 높다.

메서드로 공통 코드를 분리하면 코드가 더 간단해진다고 생각할 수 있지만, 통상 쿼리 표현식 내 람다 표현식은 델리게이트로 변환되어 수행하기 때문에 틀린 말이 된다.

복잡한 쿼리에서 람다 표현식을 재사용하는 효율적인 방법

  • 닫힌 제네릭 타입에 대해 쿼리를 위한 확장 메서드를 작성한다.

아래 LowPaidSalariedFilter가 그런 메서드에 해당한다.
전체 Employee 시퀀스를 매개변수로 받아서 조건에 부합하는 요소만을 반환한다.

private static IQueryable<Employee> LowPaidSalariedFilter
    (this IQueryable<Employee> sequence) =>
        from s in sequence
        where s.Classification == EmployeeType.Salary &&
        s.MonthlySalary < 4000
        select s;

var allEmployees = FindAllEmployees();

var salaried = allEmployees.LowPaidSalariedFilter();

var earlyFolks = salaried.Where(e => e.YearsOfService >= 20);

var newest = salaried.Where(e => e.YearsOfService < 20);
반응형