(매개변수들) => 식 또는 {코드블록}
(x,y) => x+y : 하나의 식이면 { } 생략 가능하다.
x => x+4 : 매개변수가 1개이면 () 생략 가능하다.
(x, y) => { return x+y; } 코드가 여러줄이면 { }와 return 필요
람다식 내부에서, 외부에 선언된 변수를 참조하거나 수정할 수 있다.
이 때, 람다식은 해당 외부변수를 자신과 함께 기억하고 다니는데, 이를 클로저(closure)라고 한다.
for문 안에서 람다를 만들 때, 외부 변수를 캡처(기억)하는 특성 떄문에 모든 람다가 같은 변수를 공유하는 문제가 발생 가능하다.
예제
List<Action> actions = new List<Action>();
for(int i = 0; i<3; i++)
{
actions.Add() => Console.WriteLine(i));
}
foreach(var action in actions)
{
action();
}
결과(예상vs실제)
왜 이런 결과가 나왔을까?
for문의 i는 하나의 변수이다.
람다식이 i를 캡처할 때, i의 현재 값을 복사하는 것이 아니라, i 자체를 참조한다.
for문이 끝난 후 i는 3이 되어 있고, 모든 람다가 그 3을 바라본다.
해결 방법
i를 복사한 새로운 지역변수를 만들어서 캡처하면 된다.
for(int i = 0; i<3; i++)
{
int temp = i; // 복사
actions.Add(()=> Console.WriteLine(temp));
}
foreach(var action in actions) { action(); }