본문 바로가기
- C#/C# is 도샵

[C#] Lambda Expression 람다식

by david_동근 2025. 8. 24.

Lambda, 대학교에서 수학 배울 때 선형대수학의 고유값(eigen) 이랑

다변수 미적분 교과목에서 라그랑주(Lagrange)승수 법이라고 배울때,

계수 붙일 때 사용하는 느낌으로 자주 쓰는 기호 λ 입니다. (가물가물하지만 그랬던 거 같아용)

프로그래밍에서는 간단하게 메서드를 표현하고자 할 때 사용하는 것을 람다식이라 합니다.

나 같은 sheep 새끼를 lamb(da) 라고 부릅니다.

 


 

람다식 (Lambda Expression)

함수에서 매개변수를 간단히 전달해 바로 사용하고 싶을때 사용할 수 있는 표현식으로써,

무명함수 (Amomymous Function) 라고 합니다.

가장 기본적인 문법 모양은 아래와 같습니다.

(Parameters) => {Expression};

 

Parameter 가 매개인자, Expression 이 실행할 문장 코드가 되겠습니다.

 

몇 가지 예로 보겠습니다.

  • 인자 없이 : () => GetYourName()
  • 인자 1개 : x => x * x
  • 인자 2개 : (x, y) => x / y
  • 코드 2줄 이상 : (x) => { int y = x * x; return y; }

이렇게 한 번만 쓸 간단한 함수 등 짧게 적고 끝내고 싶을 때 사용할 수 있습니다.

또 다른 예시 코드 스니펫 몇가지를 보겠습니다.

//x랑 y는 각각 ID 라는 파라미터를 갖고 있다고 하고
list.Sort((x, y) => x.ID.CompareTo(y.ID));

 

람다로 list 안에 있는 요소 (진짜 요소 이름이 아녀용) x, y 를 비교해서 순서를 결정하는 코드입니다.

(음수면 x 가 빠른 번호로, 0 이면 같고, 양수면 x 가 뒷 번호로 가용)

위 코드를 다르게 표현하고자 하면 아래처럼도 가능할 겁니다.

int CompareByUsersID(User x, User y) => x.ID.CompareTo(y.ID);
// => 로 {중괄호} 랑 return 을 생략 한 겁니다요, 이걸 bodied-expression (본문식 표현) 이라고 불러요
list.Sort(CompareByUsersID);

 

추가로, 람다를 사용할 때 개인적으로 어려웠던 부분들을 아래에 정리해 보았습니다.

 

Delegate & Lambda

여기서 저는 delegate 는 '소켓 ', lambda 는 '플러그 ' 처럼 이해해서 기억을 해두었습니다.

(목표하는 소켓의 타입이 있으면, 그 타입에 따라 람다가 딱 맞게 들어가기 때문이죠)

https://bulletprooves.tistory.com/12

 

[C#] Callback, Delegate | Asynchronous 비동기 프로그래밍

비동기 프로그램 (Asynchronous Programming) 이란?하나의 메서드 결과가 반환될 때까지 기다리지 않고, 다음 작업을 요청하는 방식으로,Callback 메서드에서 결과를 기다리는 방식으로 병렬처리 효율성

bulletprooves.tistory.com

(Action 하고 Func 는 위 링크에다 정리해 두었어요)

 

Action

먼저 첫번째 예시로 Action 을 보자면,

Action a0 = () => SetMyName("david"); // 입력 0개
Action<int> a1 = x => SetMyAge(x); // 1개
Action<int, string> a2 = (h, s) => SetMyHeightAndSex(h, s); // 2개

 

해당 코드를 수행하고 반환하지 않는, 다시 말해 (입력) => void 인 셈 입니다.

 

Func

두번째 예시로 Func 는, 모양은 Func<T1, TResult> 으로 마지막이 반환형 입니다.

Func<int, int> f0 = x => x + 1; 		// int -> int
Func<string, int> f1 = s => s.Length; 	// string -> int
Func<int, int, int> add = (x, y) => x * y; // (int, int) -> int

 

Action 이 반환값이 없으면, Func 는 마지막 부분의 제네릭이 반환형이다, 로 기억하시면 될 것 같습니다.

 

etc.

Predicate<T> 는 Func<T, bool> 이라 보시면 되지 않을까 싶습니다. (아래처럼, bool 만 쓰는것 같아요)

Predicate<User> readyToRun = u => u.IsGay; // user -> bool

// LINQ 도 아래와 같아요

bool prepareToRun = User.Where(u => u.IsGay);

 

 

Target Type (목표타입)

컴파일러가 람다의 입/출력 타입을 알아야 합니다.

그렇기에 컴파일러는 소켓(delegate)의 모양을 확인해 매개인자의 타입을 결정합니다.

아래 예시를 보겠습니다.

// 변수의 대입 자리
Func<int, int> fun = x => x * x; // 왼쪽 타입이 목표타입 -> x 는 int 결과도 int

// 메서드의 인자 자리
list.Sort((x, y) => x.Height.CompareTo(y.Height));
// 위에서 말했 듯이 Comparison<User> 를 받아요 -> (User, User) 는 int 로 확정이죠

// 이건 땡~!
var fun = x => x + 1; // x 가 무슨 타입인지 알 길이 없읍죠, 대신 아래 처럼 써야해유

Func<int,int> f = x => x + 1; // 왼쪽에 목표 타입
var g = (int x) => x + 1; // 매개인자 타입을 람다 쪽에

 

다시 말해, 어딘가에는 반드시 타입의 힌트가 있어야 람다의 형태도 정해지는 것입니다.

그렇기 때문에, 오버로드 를 사용할 때도 람다의 매개변수 개수나 반환형을 잘 정해주어야 합니다.

 

늘, 꼭, 왼쪽에 타입을 쓰거나, 람다 매개변수 타입을 적거나 캐스팅 해야 합니다.

 

추가

list.Sort((x, y) => x.ID.CompareTo(y.ID));

 

int CompareByUsersID(User x, User y) => x.ID.CompareTo(y.ID);

list.Sort(CompareByUsersID);

 

는 동일한 정렬 규칙을 전달하는 코드입니다.

여기서 List<T>.Sort 는 비교함수 Comparison<T> (델리게이트) 를 받기 때문에,

아래와 같이 정리할 수 있습니다.

public void Sort(Comparison<T> comparison) // 오버로드 된 걸 거에요
public delegate int Comparison<in T>(T x, T y);

 

위 에서 2개의 T 를 받을 때, 음수는 (x<y) x 가 앞에, 0 은 같고, 양수는 (x>y) y 가 앞에 옵니다.

그래서 위의 제가 작성한 list.Sort 코드 람다처럼 '음/0/양' 의 규칙을 맞추는 비교기 역할을 합니다.

 


 

그럼 오늘도 좋은 하루 되시길 바라요~

안뇽~ (  ˵•́ ᴗ •̀˵)

'- C# > C# is 도샵' 카테고리의 다른 글

[C#] [Unity] C# Action 과 UnityAction  (0) 2025.11.19
[C#] ref, out, in 키워드  (3) 2025.08.30
[C#] HashSet<T>  (1) 2025.06.17
[C#] virtual abstract interface  (0) 2025.05.20
[C#] System.Array & Copy  (0) 2025.05.12