[객체지향] 5.LINQ와 함수형 프로그래밍 요소, 지연 평가와 IEnumerable의 사용 예

C#은 객체 지향 프로그래밍 언어로 시작했지만, 최근 몇 년 동안 함수형 프로그래밍 요소도 지원하게 되었습니다. 이로 인해 개발자들은 더욱 유연하고 강력한 방식으로 데이터를 처리할 수 있게 되었습니다. LINQ(Language Integrated Query)는 이러한 변화의 상징적인 요소 중 하나로, 데이터 소스에 대한 쿼리를 직관적으로 작성할 수 있게 해줍니다. 본 글에서는 LINQ의 기본 개념에서부터 함수형 프로그래밍의 요소, 지연 평가, IEnumerable의 사용 사례까지 상세히 알아보겠습니다.

1. LINQ란 무엇인가?

LINQ는 ‘Language Integrated Query’의 약자로, C# 언어에 내장된 쿼리 언어입니다. LINQ를 사용하면 객체, XML, 데이터베이스 등을 쿼리할 때 통일된 문법을 사용할 수 있습니다. 이를 통해 데이터 조작이 보다 직관적이고 효율적으로 이루어질 수 있습니다. LINQ는 두 가지 방식으로 사용할 수 있습니다: 쿼리 표현식과 메서드 구문.

1.1. 쿼리 표현식


var result = from student in students
             where student.Age > 20
             select student;

1.2. 메서드 구문


var result = students.Where(s => s.Age > 20);

위의 두 예에서 알 수 있듯이, LINQ는 다양한 데이터 소스에 대해 일관된 쿼리 작성을 가능하게 해줍니다.

2. 함수형 프로그래밍 요소

함수형 프로그래밍은 프로그래밍 패러다임 중 하나로, 계산의 기본 단위를 수학적 함수로 간주합니다. C#에서는 Lambda 표현식을 통해 함수형 프로그래밍을 지원합니다. Lambda 표현식은 간결하고 읽기 쉬운 형태로, 익명 메서드를 정의하는 데 사용됩니다.

2.1. Lambda 표현식 예제


Func square = x => x * x;
int result = square(5); // result는 25

위의 예에서 볼 수 있듯이, Lambda 표현식은 간편하게 함수형 프로그래밍 스타일로 코드를 작성할 수 있게 해줍니다.

3. 지연 평가(Lazy Evaluation)

지연 평가는 표현식의 평가를 가능한 한 마지막 순간까지 미루는 방식입니다. C#의 LINQ는 기본적으로 지연 평가 방식을 사용합니다. 즉, 쿼리의 실행은 실제로 데이터를 요청할 때까지 발생하지 않습니다. 이는 성능을 최적화하고 불필요한 연산을 피하는 데 도움이 됩니다.

3.1. 지연 평가의 예


IEnumerable numbers = Enumerable.Range(1, 100);
IEnumerable evenNumbers = numbers.Where(n => n % 2 == 0);

// 실제로 데이터를 요구할 때까지 평가되지 않음
foreach (var number in evenNumbers)
{
    Console.WriteLine(number);
}

위의 코드에서, evenNumbersnumbers의 짝수값을 필터링하는 쿼리를 정의하지만, 이 쿼리는 실제로 데이터를 요구할 때까지 실행되지 않습니다.

4. IEnumerable 인터페이스의 사용

IEnumerable 인터페이스는 컬렉션을 반복할 수 있게 해주는 기본 인터페이스입니다. LINQ는 IEnumerable을 반환함으로써 지연 평가와 함수형 프로그래밍의 개념을 사용합니다. IEnumerable을 통해 순차적으로 데이터를 처리하며, 필요한 경우에만 데이터를 로드하여 성능을 최적화합니다.

4.1. IEnumerable의 사용 예


public static IEnumerable GetEvenNumbers(IEnumerable numbers)
{
    foreach (var number in numbers)
    {
        if (number % 2 == 0)
        {
            yield return number; // 지연 반환
        }
    }
}

// 호출 예제
IEnumerable evenNumbers = GetEvenNumbers(Enumerable.Range(1, 100));
foreach (var number in evenNumbers)
{
    Console.WriteLine(number);
}

위 예제에서 yield return 키워드를 사용하여 수를 하나씩 반환하고 있습니다. 이는 호출 시까지 값을 미루어 놓았다가 필요할 때만 반환하는 지연 평가의 한 형태입니다.

5. LINQ와 IEnumerable의 결합

LINQ는 IEnumerable과 밀접하게 연관되어 있습니다. LINQ를 사용하여 IEnumerable을 쿼리하면 지연 평가가 발생하고, 필요한 데이터만을 효율적으로 작업할 수 있습니다.

5.1. LINQ 쿼리 예제


IEnumerable numbers = Enumerable.Range(1, 50);
var squaredEvenNumbers = numbers.Where(n => n % 2 == 0).Select(n => n * n);

// 지연 평가를 확인
foreach (var number in squaredEvenNumbers)
{
    Console.WriteLine(number);
}

위에서의 LINQ 쿼리는 짝수인 수를 제곱하여 그 결과를 나중에 출력하게 됩니다. LINQ를 사용하면 코드가 더욱 더 선언적이며 간결해집니다.

결론

LINQ와 함수형 프로그래밍 요소, 지연 평가 및 IEnumerable의 사용은 C# 프로그래밍을 더욱 확장 가능하고 유지 보수가 용이하게 만듭니다. 이들 특징을 적절히 활용하면 효율적인 데이터 처리 및 강력한 코드 작성을 가능하게 할 수 있습니다. C#을 사용하는 개발자라면 이러한 개념들을 깊이 있게 이해하고 활용하는 것이 중요합니다.

참고 자료