Computer >> 컴퓨터 >  >> 프로그래밍 >> C#

C# 람다 표현식(Lambda Expression) 완벽 정리: 개념, 문법, 활용법

C# 람다 표현식이란 무엇인가?

람다 표현식(Lambda Expression)은 익명 메서드(anonymous method)를 더욱 간결하고 직관적으로 표현할 수 있는 방법입니다. 익명 메서드와 람다 표현식 모두 메서드 구현을 코드 내에서 인라인(in-line)으로 정의할 수 있다는 공통점이 있지만, 익명 메서드는 매개변수 타입과 반환 타입을 명시적으로 선언해야 하는 반면, 람다 표현식은 컴파일러가 타입을 추론하므로 훨씬 짧고 읽기 쉬운 코드를 작성할 수 있습니다.

람다 표현식의 두 가지 형태

람다 표현식은 본문(body)의 구성에 따라 두 가지 형태로 나뉩니다.

1. 식 람다(Expression Lambda)

오른쪽에 하나의 식(expression)을 본문으로 가지며, 그 식의 결과값을 반환합니다.

(input-parameters) => expression

2. 문 람다(Statement Lambda)

중괄호로 묶인 문장 블록(statements block)을 본문으로 가집니다.

(input-parameters) => { <sequence-of-statements> }

대리자(Delegate)로의 변환

모든 람다 표현식은 대리자(delegate) 타입으로 변환될 수 있습니다. 변환 가능한 대리자 타입은 람다 표현식의 매개변수 타입과 반환값 타입에 의해 결정됩니다.

  • 반환값이 없는 경우 → Action 계열 대리자로 변환
  • 반환값이 있는 경우 → Func 계열 대리자로 변환

다음은 Func<int, int> 대리자에 람다 표현식을 할당하는 기본적인 예제입니다.

static void Main(string[] args)
{
    Func<int, int> square = x => x * x;
    Console.WriteLine(square(5)); // 출력: 25
    Console.ReadLine();
}

식 람다 활용 예제

=> 연산자 오른쪽에 식이 오는 람다를 식 람다(expression lambda)라고 부르며, 다양한 형태로 활용할 수 있습니다.

// 매개변수가 없는 경우
Action line = () => Console.WriteLine();

// 단일 매개변수
Func<double, double> cube = x => x * x * x;

// 여러 매개변수
Func<int, int, bool> testForEquality = (x, y) => x == y;

// 매개변수 타입을 명시적으로 지정하는 경우
Func<int, string, bool> isTooLong = (int x, string s) => s.Length > x;

일반적으로 컴파일러가 타입을 추론할 수 있지만, 타입 추론이 어렵거나 코드 가독성을 높이고 싶을 때는 위 마지막 예제처럼 입력 매개변수의 타입을 명시적으로 지정할 수 있습니다.

C# 7.0 이상: 튜플(Tuple) 지원

C# 7.0부터 언어 차원에서 튜플(tuple)이 기본 지원되면서, 람다 표현식에도 튜플을 활용할 수 있게 되었습니다. 튜플을 람다 표현식의 인수로 전달할 수 있으며, 람다 표현식이 튜플을 반환하도록 작성하는 것도 가능합니다.

Func<(int a, int b), (int sum, int product)> calc = t => (t.a + t.b, t.a * t.b);
var result = calc((3, 4));
Console.WriteLine(result.sum);     // 출력: 7
Console.WriteLine(result.product); // 출력: 12

람다 표현식 사용 시 주의사항 및 제약 조건

람다 표현식을 사용할 때 반드시 알아두어야 할 중요한 규칙들이 있습니다.

  • 변수 범위(Scope): 람다 표현식 내부에서 선언된 변수는 외부를 감싸고 있는(enclosing) 메서드에서는 보이지 않습니다.
  • ref/out 매개변수: 람다 표현식은 감싸고 있는 메서드의 in, ref, out 매개변수를 직접 캡처(capture)할 수 없습니다.
  • return 문: 람다 표현식 내부의 return 문은 감싸고 있는 메서드 전체를 종료시키지 않으며, 해당 람다 표현식 자체의 반환만 의미합니다.
  • 점프 문(jump statement) 제한: 람다 표현식 안에서 goto, break, continue 문의 대상(target)이 람다 블록 외부에 있다면 컴파일 오류가 발생합니다. 반대로 람다 블록 외부의 점프 문이 블록 내부를 대상으로 하는 것 역시 허용되지 않습니다.

마무리

람다 표현식은 LINQ 쿼리 작성, 이벤트 처리, 비동기 프로그래밍 등 현대 C# 개발에서 필수적인 요소입니다. 익명 메서드보다 간결한 문법과 함께 Func, Action 대리자와의 자연스러운 호환성 덕분에 코드의 가독성과 생산성을 크게 향상시킬 수 있습니다. 위에서 소개한 문법과 제약 사항을 잘 숙지하고 활용한다면, 더 깔끔하고 유지보수하기 좋은 C# 코드를 작성할 수 있을 것입니다.