오늘은 람다(Lambda)식에 대해서 알아보겠습니다. 람다식은 익명 메소드를 만들기 위해 사용하는데요, 무명 함수(Anonymous Function)라고도 불립니다.
일반 메소드를 보면 매개 변수와 반환값을 가지고 있는것처럼, 람다식도 마찬가지로 매개변수와 반환값을 가지고 있지요.
기본적인 람다식을 선언하는 형식은 다음과 같습니다.
매개 변수 목록 => 식
여기서 => 연산자는 무엇일까요, 이 연산자는 '입력' 연산자 입니다. 이 연산자가 하는 역할은 그저 매개변수를 전달하는 것 뿐입니다.
람다식에서는 =>를 중심으로 왼편에는 매개변수가, 오른편에는 식이 위치합니다. 코드로 먼저 보겠습니다.
1
2
3
4
5
6
7
8
9
10
|
// 익명의 메소드를 만들려면 델리게이트가 필요합니다.
delegate int Calculate(int a, int b);
static void Main(string[] args)
{
// 두 개의 int 형식 매개변수 a,b를 받아 이 둘을 더해 반환하는 익명메소드를 람다식으로 만들었습니다.
Calculate calc = (int a, int b) => a + b;
calc(1, 2);
| cs |
C#컴파일러는 위 코드를 한층 더 간결하게 만들 수 있도록 '형식 유추(Type Inference)'라는 기능을 제공합니다. 형식유추를 이용하면 다음과 같이 람다식에서 매개변수의 형식을 제고할 수 있습니다.
1
2
3
4
|
// C#컴파일러는 델리게이트의 선언 코드로부터 매개 변수 형식을 유추합니다.
Calculate calc = (a, b) => a + b;
calc(1, 2);
| cs |
다음은 델리게이트를 이용해서 재구현한 코드입니다.
1
2
3
4
5
6
7
8
|
delegate int Calculate(int a, int b);
static void Main(string[] args)
{
Calculate calc = delegate (int a, int b)
{
return a + b;
};
| cs |
이렇게 여러 코드를 보았을 때 델리게이트보다 람다식이 더 간결하다는 것을 느끼실수 있습니다.
지금까지 살펴본 람다식은 '식(Expression)'형식을 하고 있습니다. 이번에는 '문 형식의 람다식(Statement Lambda)'에 대해 알아보겠습니다. 문 형식의 람다식이란
간단히 a + b나 a == b의 식이 아니라 if(a == b) return 0; else return 1; 과 같은 문장을 말합니다.
문 형식의 람다식은 => 연산자의 오른편에 식 대신 {}로 둘러싸인 코드 블록이 위치합니다.
매개변수목록 => { 문장1; 문장2; 문장3; … }
위 식을 보면 반환 형식과 매개 변수가 없는 델리게이트를 사용하고 있습니다. 식 형식의 람다식으로는 반환 형식이 없는 무명함수를 만들 수 없지만, 문 형식의 람다식을 이용하면 가능합니다.
1
2
3
4
5
6
7
8
9
10
11
|
delegate void DoSomething();
static void Main(string[] args)
{
// 매개변수가 없을 때는 빈공간으로 두면 됩니다.
DoSomething Doit = () =>
{
string str1 = "뭔가를";
string str2 = "뭐라도";
string str3 = "넣어보자..";
};
| cs |
이번에는 더 간편하게 무명함수를 만드는 방법에 대해서 알아보겠습니다. 방법은 바로 Func와 Action입니다.
이 요소들은 익명 메소드와 무명 함수의 코드를 좀 더 간결하게 만들어줍니다. 이전 익명 메소드를 만들 때 매번 델리게이트를 선언하였습니다. 이것 또한
번거롭다면 번거로울 수 있는 일이겠지요. 이 문제를 해결하기 위해 .NET 프레임워크에 Func와 Action 델리게이트를 미리 선언해두었습니다.
Func델리게이트는 결과를 반환하는 메소드를 참조하기 위해,
Action 델리게이트는 결과를 반환하지 않는 메소드를 참조하기 위함입니다.
먼저 Func 델리게이트에 대해서 알아보겠습니다.
Func델리게이트는 결과를 반환하는 메소드를 참조하기 위해 만들어졌습니다. .NET 프레임워크에는 모두 17가지 버전의 Func 델리게이트가 준비되어 있습니다.
1
2
3
4
5
6
7
|
public delegate TResult Func<out TResult>();
public delegate TResult Func<in T, out TResult>(T arg);
public delegate TResult Func<in T1, int T2, out TResult>(T1 arg1, T2 arg2);
….
| cs |
모든 Func 델리게이트의 형식 매개변수 중 가장 마지막에 있는 것이 반환 형식입니다.
형식 매개변수가 하나뿐인 Func는 그 하나가 반환 형식이고, 형식 매개 변수가 두개인 Func은 두번째가 되겠고, 형식 매개변수가 세개인 Func은 세번째가 되겠습니다. 이런식으로 17개의 형식 매개변수를 가진 Func은 17번째 형식 매개변수가 반환 형식이 되겠지요. 이 처럼 Func델리게이트는 입력 매개변수가 하나도 없는 것부터 16개에 이르는 것까지 버전이 다양하기 때문에 어지간한 경우가 아니면 종류내에서 사용하실 수 있습니다.
1
2
3
4
5
6
7
8
|
// 입력 매개변수는 없으며, 무조건 10을 반환합니다.
Func<int> func1 = () => 10;
//입력 매개변수는 int형 한 개며, 반환 형식도 int형입니다.
Func<int, int> func2 = (x) => x * 10;
int result = func1();
int result2 = func2(10);
| cs |
그다음 Action 델리게이트에 대해 알아보겠습니다.
Action델리게이트도 Func 델리게이트와 거의 똑같습니다. 차이점이라면 Action델리게이트는 반환 형식이 없다는 것 뿐이지요.
Action델리게이트도 .NET프레임워크에 17개 버전이 선언되어있습니다.
1
2
3
4
5
6
7
|
public delegate void Action<>();
public delegate void Action<in T>(T arg);
public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2);
….
| cs |
Action 델리게이트의 형식 매개변수는 모두 입력 매개변수를 위해 선언되어 있습니다. Func와는 달리 어떤 결과를 반환하는 것을 목적으로 하지 않고, 일련의 작업 수행을 목적으로 하기때문입니다.
1
2
3
4
5
6
|
int idata = 0;
Action act1 = () => idata = 10;
Action<int> act2 = (x) => idata = x * 10;
| cs |
1
|
act1();
| cs |
1
|
act2(10);
| cs |