본문 바로가기

C#

C# 람다식(Lambda Expressions)

표현 방법

(매개변수) => {식 또는 구문}

람다식은 주로 아래와 같은 용도로 사용된다.

  • Delegate 인스턴스(대리자 매개변수 자리에 람다식으로 대입함)
  • 식 트리(Expression Tree) Expression를 만드는데 사용

예시1: 기본 사용 문법

아래와 같이 쓰일 수 있다.

x=> 3.14*x*x;
(int x) => 3.14*x*x;
(s1, s2) => s1.Length + s2.Length;
() => Console.WriteLine("람다식");
() => {int num = 1; num++; };

예시2: 대리자와 람다식

대리자 인스턴트이기 때문에 다음과 같이 표준 대리자에 할당 가능하다.

Func<int,int> circleArea = x => 3.14*x*x;
Func<string,string,int> totalLength = (s1, s2) => s1.Length + s2.Length;
Action message = () => Console.WriteLine("람다식");

예시3: 매개변수의 형식 명시적 지정

void Dummy<T> (T x) { ... }
void Test<T> (Action<T> a) { ... }
Test (x => Dummy(x)) //컴파일 에러. x의 타입을 추론하지 못함.
Test ((int x) => Dummy(x)); //잘 작동함.
Test<int> ( x => Dummy(x)); //Test의 형식을 특정해서 해결
Test<int> (Dummy); //위와 같지만 메서드 그룹으로(대리자로 함수 자체를 할당해 넘길 때 변수 괄호를 넣지 않음)

예시4: 람다식 밖의 변수 사용

int num = 2;
Func<int, int> binary = n => n % num;
Console.WriteLine(multiplier(5)); //1

람다식의 변수 할당은 마지막에 일어난다.

Action[] action = new Action[3];
for (int i = 0; i < 3; i++)
{
    action[i] = () => Console.Write(i);
}
foreach (Action a in action) a(); //333

좀 더 풀어써보면 아래와 같은 동작 원리를 알 수 있다.

Action[] action = new Action[3];
int i = 0;
action[0] = () => Console.Write(i);
int i = 1;
action[1] = () => Console.Write(i);
int i = 2;
action[2] = () => Console.Write(i);
int i = 3;
foreach (Action a in action) a(); //333

아래의 경우 변수 n이 반복마다 생성되고 사라지기 때문에 각각의 값으로 할당되게 된다.

Action[] action = new Action[3];
for (int i = 0; i < 3; i++)
{
    int n = i;
    action[i] = () => Console.Write(n);
}
foreach (Action a in action) a(); //012

C# 5.0 이후 부터는 아래와 같은 foreach 구문에서는 c라는 값이 주기마다 생성되고 사라지는 형태로 통일됐다.

Action[] action = new Action[3];
int i = 0;
foreach (char c in "abc")
    action[i++] = () => Console.Write(c);

foreach (Action a in action) a(); //abc
//ccc로 출력 c# 4.0 이하 버전에서는

Lambda Expression(람다식)과 Local Method(지역함수) 비교

Local Method의 장점

  1. 재귀적인 정의가 가능. 자기 자신을 다시 불러 올 수 있음.
  2. 특정 delegate type에 담기지 않는다.
  3. 메모리 효율이 약간 더 좋다.

Lambda Expression의 장점: 익명메서드로 delegate의 생략을 통한 표현의 간결화

참고문헌: C# 8.0 in a Nutshell, Joseph Albahari. Eric Johannsen.

'C#' 카테고리의 다른 글

C# EventHandler 표준 이벤트 구현  (0) 2020.11.27
C# 이벤트(Events)  (0) 2020.11.26
C# 확장 메서드(Extension Methods)  (0) 2020.11.15
C#코딩의 기술 010. 클래스 하나로 증후군  (0) 2019.01.30
009. 불필요한 형변환 남용  (4) 2019.01.30