포스트

[C#] 람다 함수 알아보기

람다 연산자

C#에서 람다 식은 익명의 함수를 만들 수 있는 기능입니다.
즉, 함수의 이름이 존재하는 일반 함수와 다르게 이름을 선언하지 않고 사용할 수 있습니다.

이러한 람다식은 람다 연산자 =>를 사용해서
짧은 코드를 작성할 수 있고 그로 인해서 코드의 가독성을 향상 시킬 수 있다는 효과가 있습니다.

아래는 간단한 예제로 함수를 호출하여 곱하기 2를 한 값을 반환하는 함수입니다.

1
2
3
4
5
6
7
8
9
10
11
class Program
{
  static int DoubleFunc(int num)
  {
    return num * 2;
  }
  static void Main(string[] args)
  {
    Console.WriteLine(DoubleFunc(10));
  }
}

위의 코드 중 DoubleFunc() 함수를 람다 식을 이용해 간단하게 만들면
아래와 같이 작성할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
class Program
{
  static void Main(string[] args)
  {
    Func<int, int> DoubleFunc = (num) => num * 2;

    int num = 10;
    Console.WriteLine(DoubleFunc(num));         
  }
}

람다 함수의 형태는 2가지로 식 람다문 람다가 있습니다.
먼저, 식 람다는 위의 코드처럼 => 연산자의 오른쪽에 식이 있는 람다 식을 식 람다라고 합니다.
문 람다의 경우, 중괄호 안에 문을 지정한다는 점을 제외하면 식 람다와 비슷합니다.

1
2
3
4
5
// 식 람다
(input-parameters) => expression

// 문 람다
(input-parameters) => { <sequence-of-statements> }


Func 대리자

Func 대리자는 0개 이상의 인수를 가지며, 마지막에 반환 타입을 작성합니다.  이전 간단한 DoubleFunc() 함수의 앞 부분에도 Func<int, int> 라는 코드가 작성되었습니다.
이 의미는 매개변수가 int형이고 반환형도 int형인 함수라는 의미입니다.
이 외에도 다양한 형태로 대리자를 사용할 수 있습니다.

1
2
3
4
5
6
7
8
Func <int, double, int> FuncMethod1;
// int형 매개변수, double형 매개변수, 반환 타입은 int형 

Func <int, int> FuncMethod2;
// int형 매개변수, 반환 타입은 int형

Func <int> Funcmethod3;
// 매개변수 없음, 반환 타입은 int 형

여기서 대리자란 ‘대신 실행해주는 것’이라는 의미로
아래와 같은 코드처럼 함수 자체를 담을 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Program
{
  static int DoubleFunc(int num)
  {
    return num * 2;
  }

  static void Main(string[] args)
  {
    Func<int, int> DoubleFuncDelegate = DoubleFunc;

    int num = 10;
    Console.WriteLine(DoubleFuncDelegate(num));         
  }
}


Func 람다식

람다 식은 익명 함수이기 때문에 Func 대리자를 사용해서 함수를 전달하지 않고
실행할 코드를 넘겨줄 수 있습니다.
따라서 이전 코드의 DoubleFuncDelegate라는 이름 없이 아래처럼 사용할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
class Program
{
    static void Main(string[] args)
    {
        Func<int, int> DoubleFuncDelegate = num => num * 2;

        int num = 10;
        Console.WriteLine(DoubleFuncDelegate(num));         
    }
}

이때, 매개 변수 개수에 따라 형식이 조금 다릅니다.
위의 코드에서는 num이라는 매개 변수 1개만 존재하였기 때문에 함수의 소괄호를 생략하였지만
2개 이상의 경우, 반드시 소괄호를 작성해야 합니다.

1
2
3
4
5
6
7
8
9
class Program
{
    static void Main(string[] args)
    {
        Func<int, int, String> DoubleFuncDelegate = (a, b) => (a + b).ToString();

        Console.WriteLine(DoubleFuncDelegate(10, 20));
    }
}


Action 대리자

Func 대리자가 반환형을 명시하는 대리자고 Action 대리자는 반환형이 없는(void) 대리자 입니다.
따라서 Action 키워드와 함께 매개 변수의 자료형만 전달받고 반환형의 자료형은 작성하지 않습니다.

1
2
3
4
5
6
7
8
Action <int, double, int> FuncMethod1;
// int형 매개변수, double형 매개변수, int형 매개변수

Action <int, int> FuncMethod2;
// int형 매개변수, int형 매개변수

Action <int> Funcmethod3;
// int형 매개변수


Action 람다식

Action 대리자를 사용한 람다 식은 Func 대리자를 사용한 람다식과 비교했을 때,
반환형이 없다는 점을 빼면 형태가 닮았습니다.

1
2
3
4
5
6
7
8
9
class Program
{
    static void Main(string[] args)
    {
        Action<int, int> ActionDelegate = (a, b) => Console.WriteLine(a + b);

        ActionDelegate(10, 20);
    }
}


로컬 대리자

Func, Action 대리자 외에 로컬 대리자를 사용해서 람다 함수를 구현할 수 있습니다.
아래는 로컬 대리자의 예시로, 다른 대리자와 유사한 형태를 갖고 있습니다.

1
2
3
int DoubleFuncDelegate(int num) => num * 2;

void ActionDelegate(int a, int b) => Console.WriteLine(a + b);


포스팅 배경

현재 진행중인 프로젝트인 SCG 프로젝트에서 스레드를 사용하고자 코드를 작성 중
스레드 객체에게 매개변수를 전달하고자 할 때, 여러 방법이 존재함을 알게 되었고,
그 중 람다함수 알게 되었습니다.

기존에 사용하던 언어인 C++의 람다 함수와 형태가 달라서
이번 포스트로 C#의 람다함수에 대해 알아보고자 작성하게 되었습니다.


참고

Microsoft learn, 람다 식 및 익명 함수
[C#]람다식, 람다표현식(Lambda expression), 강재성님 블로그

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.