람다 표현식 기본사용법

 람다식은 대리자 인스턴스가 쓰이는 곳에 쓰일 수 있는 이름 없는 메서드이다. 

 아래 예제를 통해서 설명합니다. 

delegate int delegatefunc(int i, int i2);

delegate int delegatefunc(int i, int i2);

static int multiply(int mul1, int mul2)
{
    return mul1 * mul2;
}

public static void Main(String[] args)
{
    // 함수식을 사용한 대리자 인스턴스
    delegatefunc f = multiply;
    Console.WriteLine(f(4, 5));
    // 람다식을 사용한 대리자 인스턴스
    delegatefunc f2 = (m1, m2) => m1 * m2;
    Console.WriteLine(f2(4, 5));
}

 대리자 f를 보면 실제 함수인 multiply함수를 선언 후 해당 함수를 대리자 인스턴스에 대입하였습니다. 

 대리자 f2를 보면 따로 함수를 선언하지 않고 람다식을 사용해서 간단히 대리자 인스턴스를 생성하였습니다. 

 람다식을 사용하면 이렇게 손쉽게 대리자에 대입이 가능합니다.

 람다식은 다음과 같은 방식으로 "(매개변수) => 표현식 또는 문장 블록"으로 사용 할 수 있습니다. 

 예제에서는 "multiply"함수가 "(m1, m2) => m1 * m2;"로 간단히 표현 되었습니다.

 이전에 배운 Func, Action 대리자와도 함께 쓰입니다. 

Func<int, int, int> f3 = (m1, m2) => m1 * m2;
Console.WriteLine(f3(4, 5));

 이렇게 사용하면 delegatefunc 대리자를 사용하는 것보다 손쉽게 표현될 수 있습니다.

람다 매개변수 형식

 보통은 람다의 매개변수의 형식은 컴파일러가 추론합니다. 

 "Func<int, int, int> f3 = (m1, m2) => m1 * m2" 를 보면 m1, m2의 경우 따로 형식을 지정하지 않아도

 컴파일러가 int로 추론합니다.

void Foo<T> (T x) {}
void Boo<T> (Action<T> a) {}

Boo( x => Foo(x));  		// 컴파일 에러 형식을 추론할 수 없음
Boo((int x) => Foo(x));		// 명시적으로 형식을 지정

 위의 예제의 경우는 컴파일러가 타입에 대해서 추론이 불가능 하기 때문에 이런 경우

 명시적으로 지정을 해줘야 합니다. 

람다의 외부 변수 갈무리

 람다식의 코드에서 자신이 정의된 메서드의 지역변수나 매개변수를 참조하는 것이 가능한데 그러한 변수들을 

 외부 변수라고 부르며 람다식이 참조하는 외부 변수를 갈무리된 변수(captured variable)라고 합니다.

 (캡쳐한다고 하는 것이 더 이해가 쉬울듯하네요.)

public static void Main(String[] args)
{
    int factor = 10;
    Func<int, int>  multiplier = n => n * factor;
    Console.WriteLine("call multiplier");
    Console.WriteLine(multiplier(2));   // print 20
    factor = 100;
    Console.WriteLine(multiplier(2));   // print 200
    
    int seed = 0;
    Func<int> natural = () => seed++;
    Console.WriteLine("call natural");
    Console.WriteLine(natural());    // print 0
    Console.WriteLine(natural());    // print 1
    Console.WriteLine(seed);         // print 2
}

결과

 예제의 multiplier 람다식을 보면 factor라는 외부변수를 캡쳐하고 있습니다. factor라는 값은 캡쳐될 때 시점이 아니라

 실제로 호출 되는 시점에 값으로 평가됩니다. 

 natural 람다식에서는 seed라는 외부변수를 자기 자신이 갱신하면 값이 갱신이 됩니다.

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

[c#] 이벤트  (0) 2019.09.24
[c#] 대리자(delegate)  (0) 2019.09.23

+ Recent posts