CS 공부

[C#] 람다식(Lambda Expression)

때류기 2024. 8. 16. 23:33

C#에서람다식(Lambda Expression)은 코드의 간결성과 가독성을 높여주는 강력한 기능입니다. 이번 글에서는 람다식이 무엇인지, 어떤 특징이 있는지, 왜 사용하는지, 그리고 어떻게 사용하는지를 예제 코드와 함께 설명하겠습니다.

 

 


1. 람다식이란?

람다식은 익명 함수(Anonymous Function)의 한 종류로서, 코드를 간단하게 표현하기 위해 사용됩니다. 이름 없는 메서드를 간단히 표현할 수 있으며, 함수를 매개 변수로 전달하거나 즉시 실행해야 하는 경우에 유용합니다.

 

람다식은 다음과 같은 형식으로 표현됩니다:

(parameters) => expression

여기서 "parameters'는 입력 매개변수를, 'expresstion'은 실행할 코드 블록을 나타냅니다. 일반적으로 람다식은 짧고 간단한 함수들을 표현하기 위해 사용됩니다.

 

예제:

Func<int, int> square = x => x * x;
Console.WriteLine(square(5)); // 출력: 25

위 코드에서 'x => x * x'가 람다식입니다. 이 식은 'x'라는 매개 변수를 받아 'x * x'를 반환하는 익명 함수를 나타냅니다.

 

 

 


2. 람다식의 특징

람다식은 C#에서 코드의 간결성과 함수형 프로그래밍의 일부 기능을 제공하기 위해 사용됩니다.

람다식의 주요 특징은 다음과 같습니다.

 

1) 익명성

람다식은 이름이 없는 익명 함수입니다. 이는 별도의 메서드를 정의하지 않고도 함수를 사용할 수 있게 해줍니다.

 

 

2) 간결성

람다식은 코드를 간결하게 만들어줍니다. 특히, 간단한 로직을 표현할 때, 전통적인 메서드 정의보다 더 짧고 읽기 쉽게 표현할 수 있습니다.

 

기본적인 메서드 정의:

public int Square(int x)
{
    return x * x;
}

 

람다식으로 표현:

Func<int, int> square = x => x * x;

 

 

3) 함수형 프로그래밍

람다식은 C#에서 함수형 프로그래밍의 일부 개념을 구현할 수 있게 해줍니다. 함수형 프로그래밍은 함수를 일급 시민(First-Class Citizen)으로 취급하며, 함수 자체를 변수에 할당하거나 다른 함수에 전달 할 수 있습니다.

 

 

4) 표현식과 문

람다식은 하나의 표현식(단일 라인의 코드)으로 간단히 작성할 수 있지만, 여러 줄로 구성된 복잡한 로직도 처리할 수 있습니다.

 

단일 표현식:

Func<int, int> square = x => x * x;

 

여러줄로 구성:

Func<int, int, int> add = (x, y) =>
{
    int result = x + y;
    return result;
};

 

 

5) 타입 추론

람다식의 매개변수 타입은 대부분 컴파일러가 추론합니다. 명시적으로 타입을 지정할 수도 있지만, 보통은 생략합니다.

 

타입 명시적 지정:

Func<int, int> square = (int x) => x * x;

 

타입 추론:

Func<int, int> square = x => x * x;

 

 

 


3. 람다식을 사용하는 이유

1) 코드의 간결화

람다식은 코드를 간결하게 만들어 가독성을 높입니다. 특히, LINQ(Language Integrated Query)와 함께 사용될 때 매우 유용합니다.

int[] numbers = { 2, 3, 4, 5 };
var squaredNumbers = numbers.Select(x => x * x);
Console.WriteLine(string.Join(", ", squaredNumbers)); // 출력: 4, 9, 16, 25

 

 

2) 고차 함수(Higher-Order Function) 활용

람다식은 함수를 인자를 전달하거나, 함수를 반환하는 고차 함수를 쉽게 구현할 수 있게 해줍니다.

Func<int, Func<int, int>> add = x => y => x + y;
var addFive = add(5);
Console.WriteLine(addFive(3)); // 출력: 8

 

 

3) 즉시 실행 및 콜백

간단한 로직을 즉시 실행하거나, 비동기 작업에서 콜백으로 사용할 때 유용합니다.

public void A()
{
	Action<string> greet = name => Console.WriteLine($"Hello, {name}!");
	B(greet);
}

public void B(Action<string> action)
{
	action("World"); // 출력: Hello, World!
}

 

 

4) LINQ와의 통합

람다식은 LINQ쿼리에서 사용되는 주요 구성 요소입니다.  LINQ쿼리에서 데이터를 필터링하거나 변환할 때 람다식을 사용하면 매우 직관적이고 간결한 코드를 작성할 수 있습니다.

int[] numbers = { 1, 2, 3, 4, 5, 6 };
var evenNumbers = numbers.Where(x => x % 2 == 0);
Console.WriteLine(string.Join(", ", evenNumbers)); // 출력: 2, 4, 6

 

 

 


4. 람다식의 단점

람다식은 매우 유용하고 편리한 기능이지만, 몇 가지 단점과 고려해야 할 사항들이 존재하며, 람다식의 사용을 제한하거나 다른 접근법을 고려하도록 할 수 있습니다.

 

 

1. 디버깅의 어려움

람다식은 익명 함수로, 이름이 없기 때문에 디버깅이 복잡해질 수 있습니다. 특히, 여러 개의 중첩된 람다식이나 복잡한 LINQ쿼리를 디버깅할 때는 호출 스택에서 어떤 람디식이 실행 중인지 파악하기 어렵습니다.

var numbers = new[] { 1, 2, 3, 4, 5 };
var result = numbers.Where(x => x % 2 == 0).Select(x => x * x);

이 코드에서 문제가 발생하면, 어느 부분에서 예외가 발생했는지 확인하기 어려울 수 있습니다.

 

 

2. 복잡한 로직에 부적합

람다식은 간단한 로직을 포현할 때 매우 유용하지만, 복잡한 로직을 담기에는 적합하지 않습니다. 여러 줄의 코드나 복잡한 조건이 포함된 람다식은 가독성을 떨어트리고 유지보수를 어렵게 할 수 있습니다.

var complexCalculation = (int x, int y) =>
{
    if (x > y)
        return x * y;
    else if (x == y)
        return x + y;
    else
        return x - y;
};

이러한 경우에는 일반 메서드로 표현하는 것이 더 명확하고 가독성이 좋습니다.

 

 

3. 타입 안전성 문제

람다식은 컴파일러가 매개변수의 타입을 추론할 수 있지만, 일부 상황에서는 타입 추론이 올바르지 않거나 명확하지 않을 수 있습니다. 특히 복잡한 표현식에서 타입 오류가 발생할 수 있으며, 이런 경우 명시적으로 타입을 지정해야 합니다.

var calculate = (x, y) => x + y; // 컴파일러가 x와 y의 타입을 잘못 추론할 수 있음

 

 

4. 익명 함수의 재사용 불가

람다식은 익명 함수이므로, 동일한 로직을 여러 곳에서 사용해야 할 경우, 코드의 중복이 발생할 수 있습니다. 메서드나 함수로 정의된 코드와 달리, 람다식은 별도의 이름이 없기 때문에 재사용성이 떨어집니다.

// 동일한 람다식을 여러 번 작성해야 하는 경우
var list1 = numbers.Where(x => x > 5).ToList();
var list2 = numbers.Where(x => x < 3).ToList();

이와 같은 경우, 동일한 조건을 여러 번 새용해야 할 때, 중복된 코드를 방지하기 위해 별도의 메서드로 분리하는 것이 더 좋습니다.

 

 

5. 가독성 저하

람다식을 남용하거나 너무 복잡하게 사용할 경우, 코드의 가독성이 저하될 수 있습니다. 특히, 람디식에 익숙하지 않은 개발자나 팀에서는 이러한 코드를 이해하기 어려울 수 있습니다. 가독성은 코드 유지 보수성에 중요한 요소이므로, 적잘한 사용이 필요합니다.

var result = list.Where(x => x.Prop1 > 10 && x.Prop2 < 20)
                 .Select(x => new { x.Prop1, x.Prop2 })
                 .OrderBy(x => x.Prop1)
                 .ThenByDescending(x => x.Prop2)
                 .ToList();

위와 같은 복잡한 람다식은 직관적으로 이해하기 어려울 수 있으며, 코드 리뷰나 유지보수 시 불편을 초래할 수 있습니다.

 

 

 


5. 사용 방법

람다식을 사용하는 방법은 매우 다양하며, 대부분의 경우 함수와 대리자(delegate)와 함께 사용됩니다. 아래에 다양한 예제를 통해 람다식 사용 방법을 설명하겠습니다.

 

 

1) 단순한 람다식

간단한 람다식은 매개변수를 받아서 단일 표현식을 수행합니다.

Func<int, int> square = x => x * x;
Console.WriteLine(square(9)); // 출력: 81

 

 

2) 매개변수가 여러 개인 람다식

여러 매개변수를 받는 람다식도 정의할 수 있습니다.

Func<int, int, int> add = (x, y) => x + y;
Console.WriteLine(add(3, 4)); // 출력: 7

 

 

 

3) 매개변수 없이 사용 가능

매개변수가 없는 람다식도 정의할 수 있습니다.

Func<string> greet = () => "Hello, World!";
Console.WriteLine(greet()); // 출력: Hello, World!

 

 

4) 문 블록 사용

람다식은 하나의 표현식 대신 여러 줄의 문으로 구성된 블록을 포함할 수 있습니다.

Func<int, int, int> multiplyAndAdd = (x, y) =>
{
    int result = x * y;
    return result + y;
};
Console.WriteLine(multiplyAndAdd(3, 4)); // 출력: 16

 

 

5) 대리자와 함께 사용

람다식은 대리자(delegate)와 함께 사용되어 익명 함수를 대리자에할당할 수 있습니다.

Action<string> displayMessage = message => Console.WriteLine(message);
displayMessage("Lambda expressions are powerful!"); // 출력: Lambda expressions are powerful!

 

 

6) 이벤트 핸들러로 사용

이벤트 핸들러로 람다식을 사용하면 짧고 간결한 코드를 작성할 수 있습니다.

Button myButton = new Button();
myButton.Click += (sender, args) => Console.WriteLine("Button clicked!");

 

 

7) LINQ에서 람다식 사용

LINQ쿼리에서 람다식을 사용하여 데이터를 필터링하거나 변환할 수 있습니다.

int[] numbers = { 1, 2, 3, 4, 5 };
var doubledNumbers = numbers.Select(x => x * 2);
Console.WriteLine(string.Join(", ", doubledNumbers)); // 출력: 2, 4, 6, 8, 10

 

 

8) 익명 형식과의 결합

람다식은 익명 형식과 함께 사용하여 더 복잡한 데이터를 쉽게 처리할 수 있습니다.

var students = new[]
{
    new { Name = "John", Age = 18 },
    new { Name = "Jane", Age = 20 },
    new { Name = "Jake", Age = 19 }
};

var adults = students.Where(s => s.Age >= 19).Select(s => s.Name);
Console.WriteLine(string.Join(", ", adults)); // 출력: Jane, Jake

 

 

 

 


결론

람다식은 C#에서 매우 강력한 기능으로, 간결한 코드 작성과 더 나은 가독성을 제공하는 데 큰 역할을 합니다. 익명 메서드를 표현하는 람다식은 특히 LINQ, 델리게이트, 이벤트 처리, 고차 함수와 함께 사용될 때 그 진가를 발휘합니다.

이 글에서 소개한 람다식의 특징, 사용 이유, 그리고 다양한 사용 방법을 통해, 더 효율적이고 표현력 있는 C# 코드를 작성할 수 있게 될 것입니다. C# 프로그래밍에서 람다식을 적극적으로 활용해 보세요!

 

 

 


지금까지 C# 람다식에 대해 알아보았습니다.

현재 글의 내용 중 틀린 부분이나, 지적하실 내용이 있으시다면 언제든지 알려주세요! 읽어주셔서 감사합니다.