람다식은 익명 메서드를 만드는 또 하나의 방법입니다. 익명 메서드가 무엇인지 이미 알고 있다면 람다식을 이해하는 데 도움이 될 것입니다. 대리자(Delegate)로 익명 메서드를 만들 수 있는데, 마이크로소프트는 대리자가 할 수 없는 일을 람다식이 할 수 있게 C#에 이 기능을 넣었습니다.
람다(Lambda)라는 이름은 그리스 문자 람다(λ)에서 유래했습니다. 이 문자는 원래 함수를 표기하기 위한 기호로 사용되었는데, 알론조 처치라는 사람이 이 문자를 함수 표기에 사용했기 때문에 람다라는 이름이 붙었습니다.
람다식은 일반적으로 매개변수 목록 => 식 또는 문장 블록
형태로 작성됩니다. 여기서 =>
기호는 람다 연산자이며, 왼쪽에 매개변수, 오른쪽에 실행할 코드(식 또는 문장 블록)가 옵니다.
람다식에는 크게 두 가지 형식이 있습니다.
식 람다(Expression Lambda)
하나의 식으로 이루어진 람다식입니다. 반환값이 있는 경우 식의 결과가 자동으로 반환됩니다.
예를 들어, 두 개의 정수 매개변수 a와 b를 받아 합을 반환하는 식 람다는 다음과 같이 작성할 수 있습니다.
(int a, int b) => a + b
이 람다식은 int Calculate(int a, int b)
대리자와 호환될 수 있으며, C# 컴파일러는 이 람다식이 만드는 익명 메서드의 매개변수 형식을 유추합니다. 따라서 매개변수 형식을 생략하고 (a, b) => a + b
와 같이 더 간결하게 작성할 수도 있습니다.
문장 람다(Statement Lambda)
여러 문장으로 이루어진 블록 형태의 람다식입니다. 문장 블록은 중괄호 {}
로 묶습니다. 반환값이 있는 경우 return
키워드를 사용해야 합니다.
예를 들어, 문자열 배열을 받아 모든 요소를 연결하여 반환하는 문장 람다는 다음과 같습니다.
(arr) =>
{
string result = "";
foreach (string s in arr)
{
result += s;
}
return result;
}
매개변수가 없는 경우는 괄호 ()
만 사용합니다.
Func와 Action 대리자는 익명 메서드를 더 간편하게 만들기 위해 자주 사용됩니다.
Func 대리자: 반환값이 있는 익명 메서드를 참조하는 데 사용됩니다. Func<TResult>
는 매개변수 없이 TResult 타입의 값을 반환하는 함수를, Func<T, TResult>
는 T 타입의 매개변수를 받아 TResult 타입의 값을 반환하는 함수를 나타냅니다. 다양한 매개변수 개수에 대해 Func 대리자가 정의되어 있습니다 (최대 16개).
예시: Func<int, int> func2 = (x) => x * 2;
(int 매개변수를 받아 int 값을 반환)
Action 대리자: 반환값이 없는 익명 메서드를 참조하는 데 사용됩니다. Action<>
는 매개변수 없이 반환값 없는 메서드를, Action<T>
는 T 타입의 매개변수를 받아 반환값 없는 메서드를 나타냅니다. Action 대리자 역시 다양한 매개변수 개수에 대해 정의되어 있습니다 (최대 16개).
예시: Action act1 = () => Console.WriteLine("Action!");
(매개변수 없이 반환값 없는 메서드)
람다식을 Func 또는 Action 대리자 변수에 할당하여 사용할 수 있습니다.
람다식은 때때로 식 트리로 표현될 수 있습니다. 식 트리는 코드를 데이터 구조(트리 구조)로 나타낸 것입니다. 이는 특히 LINQ(Language Integrated Query)를 이해하는 데 도움이 됩니다. 식 트리는 컴파일 가능한 코드가 아닌 데이터 구조이므로, 런타임에 분석하거나 수정하거나 컴파일하여 실행할 수 있습니다.
System.Linq.Expressions
네임스페이스의 Expression
클래스는 식 트리를 만드는 데 사용되는 팩토리 메서드(Factory Method)를 제공합니다. ConstantExpression
, ParameterExpression
, BinaryExpression
등의 클래스 인스턴스를 생성하여 식 트리를 구성할 수 있습니다.
예를 들어, 1 + x
라는 식을 식 트리로 표현할 수 있습니다. 이렇게 만들어진 식 트리는 Compile()
메서드를 통해 실행 가능한 델리게이트(Func 등)로 컴파일하여 사용할 수 있습니다.
람다식과 유사한 문법을 사용하여 클래스의 특정 멤버(메서드, 속성, 인덱서, 생성자, 소멸자)를 간결하게 정의할 수 있습니다. 이를 식 본문 멤버(Expression-bodied Member)라고 합니다. =>
기호 오른쪽에 간단한 식 하나로 멤버의 내용을 표현합니다.
예시:
public void Add(string name) => list.Add(name);
public int Capacity => list.Capacity;
get => list.Capacity; set => list.Capacity = value;
public FriendList() => Console.WriteLine("FriendList()");
식 본문 멤버는 메서드나 속성의 구현이 매우 단순할 때 코드를 줄여주는 데 효과적입니다.
람다식은 익명 메서드를 간결하게 표현하고, LINQ나 식 본문 멤버 등 다양한 곳에서 활용되어 C# 코드를 더욱 유연하고 효율적으로 작성할 수 있게 해줍니다.