C# 람다식(Lambda)과 익명 함수(Anonymous Method) 차이 정리
C#에서 콜백이나 조건 함수를 전달할 때
익명 함수(delegate)와 람다식(lambda expression)을 자주 사용합니다.
겉보기에는 비슷해 보이지만, 문법·가독성·표현력에서 차이가 있습니다.
이번 글에서는 실제 코드 예제를 기반으로 두 개념의 차이를 정리합니다.
예제 코드
// 익명 함수
Item item1 = FindItem(delegate (Item item)
{
return item.ItemType == ItemType.Weapon;
});
// 람다식 (타입 명시)
Item item2 = FindItem((Item item) =>
{
return item.ItemType == ItemType.Weapon;
});
// 람다식 (타입 추론, 축약형)
Item item3 = FindItem(item => item.ItemType == ItemType.Weapon);
1️⃣ 익명 함수 (Anonymous Method)
delegate (Item item)
{
return item.ItemType == ItemType.Weapon;
}
특징
- C# 2.0에서 도입
- delegate 키워드 사용
- 매개변수 타입 반드시 명시
- 코드가 비교적 장황함
사용 사례
- 레거시 코드
- 오래된 C# 버전 유지보수
2️⃣ 람다식 (Lambda Expression)
item => item.ItemType == ItemType.Weapon
특징
- C# 3.0에서 도입
- => 람다 연산자 사용
- 타입 추론 가능
- 표현식 바디 사용 가능
- 코드가 간결하고 가독성 높음
LINQ, 이벤트, 콜백 등
현대 C# 코드의 표준 문법입니다.
3️⃣ 람다와 익명 함수 차이 한눈에 보기
구분익명 함수람다식
| 도입 버전 | C# 2.0 | C# 3.0 |
| 문법 | delegate | => |
| 타입 추론 | ❌ 불가 | ⭕ 가능 |
| 코드 길이 | 김 | 짧음 |
| 표현식 바디 | ❌ | ⭕ |
| LINQ 사용 | 제한적 | ⭕ 표준 |
| 현재 사용 빈도 | 낮음 | 매우 높음 |
* 참고
표현식 바디 : 실행 내용이 하나의 식일 때 {}와 return을 생략한 람다 문법이다.
예시
item => item.ItemType == ItemType.Weapon
4️⃣ 내부 동작은 같은가?
대부분의 경우 컴파일 결과는 동일합니다.
- 둘 다 delegate 인스턴스를 생성
- 캡처가 있으면 클로저 클래스 생성
- 성능 차이는 거의 없음
즉,
차이는 문법과 표현력이지, 성능이 아니다
5️⃣ 람다식만 가능한 기능
타입 추론
var func = x => x * 2; // ⭕
익명 함수에서는 불가능합니다.
var func = delegate (var x) { return x * 2; }; // ❌
이 때문에 LINQ와 함수형 스타일은 람다 전용입니다.
언제 무엇을 써야 할까?
✅ 람다식을 사용하는 경우
- LINQ
- 이벤트, 콜백
- 조건 전달
- 대부분의 현대 C# 코드
⚠️ 익명 함수를 사용하는 경우
- 레거시 코드 유지보수
- 구버전 C# 환경
정리
- 익명 함수와 람다식은 목적이 같다 (익명 delegate)
- 람다식은 더 간결하고 표현력이 뛰어남
- 성능 차이는 거의 없음
한 줄 요약
람다식은 익명 함수를 현대적으로 개선한 문법이며,
실무에서는 거의 항상 람다식을 사용한다.
전체 코드
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Rookiss_CSharp
{
// https://www.inflearn.com/course/%EC%9C%A0%EB%8B%88%ED%8B%B0-mmorpg-%EA%B0%9C%EB%B0%9C-part1?srsltid=AfmBOopkXVxKs-MQPYZkTjEYW-yIDMO5xP7l5hQq0hQasUWhobvyKO6N
// 59강 Lambda(람다식)
// Lambda : 일회용 함수를 만드는데 사용하는 문법
// 인벤토리 만든다는 가정
enum ItemType
{
Weapon,
Armor,
Amulet,
Ring
}
// 희귀도
enum Rarity
{
Normal,
Uncommon,
Rare
}
// 아이템
class Item
{
public ItemType ItemType;
public Rarity Rarity;
}
class Program
{
static List<Item> _items = new List<Item>();
// 아이템 찾기(특정 조건의 무기를 찾으려면 함수가 굉장히 많아짐)
// 아래처럼 하나하나 함수를 늘리는 것은 무식한 방법
/*
static Item FIndWeapon()
{
foreach (Item item in _items)
{
if (item.ItemType == ItemType.Weapon)
return item;
}
return null;
}
static Item FIndRareItem()
{
foreach (Item item in _items)
{
if (item.Rarity == Rarity.Rare)
return item;
}
return null;
}
*/
// 이를 좀 더 효울적으로 대체 가능
// 1. 델리게이트
// 아래처럼 한개의 함수로 위에 덕지덕지 붙은 함수 모두 대체가능
// delegate bool ItemSelector(Item item); // 유효한지 아닌지
// 일반화(Generic) 형식으로 사용가능
// 하나만 선언해 놓으면, 반환 형식이 있고, 입력 형식도 1개 있는 것은 모두 MyFunc() 함수로 사용가능
delegate Return MyFunc<T, Return>(T t);
// 인자 1개만 되는 형식이니까, 다르면 어떻게 할건지?
// 다른 버전을 만들어주면 됨
delegate Return MyFunc<Return>();
delegate Return MyFunc<T1, T2, Return>(T1 t1, T2 t2);
// 실제로 C#에서 이런애들이 하나씩 다 만들어져 있음 : ex) Func
// Func<> : 인자를 통해 반환하는 형식 ~ T16 까지 있음..
// 기본적으로 사용할 일이 있다면 Func<> 사용하면 됨
// Func<>
// 그러나 Func<>는 기본적으로 TResult가 있어서 반환이 있는 것만 사용함
// 반환이 없는 void 형태를 사용하려면 Action을 사용하면 됨
// Action<> : T1 ~ T16 까지 있음..
// Action<>
// 결론 : delegate를 직접 선언하지 않아도, 이미 만들어진 애들이 존재한다.
// -> Func<> : 반환 타입이 있을 경우
// -> Action<> : 반환 타입이 없을 경우
static Item FIndItem(MyFunc<Item, bool> selector)
{
foreach (Item item in _items)
{
if (selector(item)) // selector의 조건을 아이템이 무사 통과한다면 알맞는 아이템
return item;
}
return null;
}
/*
static bool IsWeapon(Item item)
{
return item.ItemType == ItemType.Weapon;
}
*/
static void Main(string[] args)
{
// 클래스를 만들면서 {} 안에 바로 넣어줄 수도 있음
_items.Add(new Item() { ItemType = ItemType.Weapon, Rarity = Rarity.Normal });
_items.Add(new Item() { ItemType = ItemType.Armor, Rarity = Rarity.Uncommon });
_items.Add(new Item() { ItemType = ItemType.Ring, Rarity = Rarity.Rare });
// 하나 아쉬운 점이 있음, 이대로 한다고 한다면 파라미터로 들어가는 함수도 결국 다 만들어 줘야함(IsWeapon, IsArmor..)
// 조건이 20개라고 한다면 20개의 함수 만들어 줘야함
// Item item = FIndItem(IsWeapon);
// 이를 람다로 일회용 함수로 대체하여 적용하는 방법이 있음(한번만 쓰고 안씀)
// 익명 함수 / 무명 함수(Anonymous Function) : 람다식 아님X
Item item1 = FIndItem(delegate (Item item) { return item.ItemType == ItemType.Weapon; });
// 람다식 : 일회용 함수를 만드는데 사용하는 문법
// 익명 함수보다 더 간단히 표현하기 위해 사용됨
// 표현 : 왼쪽 입력되는 값 => 오른쪽 반환되는 값
/*
Item item1 = FIndItem((Item item) =>
{
return item.ItemType == ItemType.Weapon;
});
*/
Item item2 = FIndItem((Item item) => { return item.ItemType == ItemType.Weapon; });
Item item3 = FIndItem(item => item.ItemType == ItemType.Weapon); // 더 간단히 가능
// 여러개 함수를 연결하여 한번에 사용 가능하고, delegate를 활용하여 함수 재사용 가능
// MyFunc<Item, bool> selector = (Item item) => { return item.ItemType == ItemType.Weapon; };
MyFunc<Item, bool> selector = (item => item.ItemType == ItemType.Weapon);
selector += item => item.ItemType == ItemType.Armor;
FIndItem(selector);
// 이미 만들어져있는 Func<>로 대체 가능
// Func<Item, bool> selector = (item => item.ItemType == ItemType.Weapon);
}
}
}
출처
[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part1: C# 기초 프로그래밍 입문| Rookiss - 인프런 강
현재 평점 4.9점 수강생 6,987명인 강의를 만나보세요. 기초 프로그래밍 지식이 없는 사람들을 위한 C# 프로그래밍 기초 강의입니다. 문법 암기 위주의 수업이 아니라, 최대한 필요한 부분만을 요
www.inflearn.com
59강 lambda(람다)
'C# > 기본 문법' 카테고리의 다른 글
| C# Reflection(리플렉션) (0) | 2025.12.14 |
|---|---|
| C# Exception(예외처리) (0) | 2025.12.14 |
| C# Event(이벤트) (0) | 2025.12.14 |
| C# Delegate(대리자) (0) | 2025.12.14 |
| C# Property(프로퍼티) (0) | 2025.12.14 |