본문 바로가기

C#/기본 문법

C# lambda(람다)

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);
        }
    }
}

 

 

 

 

 

 

 


 

 

 

출처


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

 

[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