본문 바로가기

카테고리 없음

Reflection / Delegate / Event 완전 정복

C#을 일정 수준 이상 사용하다 보면 반드시 마주치게 되는 개념들이 있다. 바로 Reflection, Delegate, Event이다.

이 세 가지는 단순한 문법 요소가 아니라, 프레임워크 설계, 라이브러리 개발, DI 컨테이너, ORM, UI 프레임워크의 핵심 기반 기술이다.


1️⃣ Reflection 이란?

Reflection은 실행 중(Runtime)에 타입 정보를 동적으로 조회하고 조작할 수 있는 기능이다.

즉, 컴파일 시점에 타입을 알지 못해도,

  • 클래스 이름
  • 메서드 목록
  • 프로퍼티
  • 필드
  • 어트리뷰트

등을 런타임에 분석할 수 있다.

Reflection이 필요한 이유

  • 플러그인 구조 구현
  • DI 컨테이너 내부 동작
  • ORM (Entity Framework)
  • Serializer / Mapper
  • 테스트 프레임워크

Reflection 기본 예제


using System;
using System.Reflection;

class Sample
{
    public int Number { get; set; }
    public void Print() => Console.WriteLine("Hello Reflection");
}

class Program
{
    static void Main()
    {
        Type type = typeof(Sample);

        Console.WriteLine(type.FullName);

        foreach (MethodInfo method in type.GetMethods())
        {
            Console.WriteLine(method.Name);
        }
    }
}

위 코드는 Sample 타입의 메서드 정보를 런타임에 조회한다. 이러한 방식은 프레임워크 내부에서 매우 빈번하게 사용된다.

객체 동적 생성


Type type = typeof(Sample);
object instance = Activator.CreateInstance(type);

이 방식은 클래스 이름만 문자열로 알고 있어도 객체를 생성할 수 있다는 점에서 플러그인 아키텍처의 핵심이다.

📘 Microsoft 공식 문서: Reflection 개요 - Microsoft Docs

 

.NET의 리플렉션

.NET에서 리플렉션을 검토합니다. 로드된 어셈블리 및 클래스, 인터페이스, 구조체 및 열거형과 같이 그 안에 정의된 형식에 대한 정보를 가져옵니다.

learn.microsoft.com

 


2️⃣ Delegate (대리자)

Delegate는 메서드를 변수처럼 다룰 수 있게 해주는 타입이다.

C#에서 Delegate는 함수 포인터의 안전한 형태라고 볼 수 있으며, 이벤트, 콜백, 비동기 처리의 핵심 요소이다.

Delegate 기본 구조


delegate int Calculate(int a, int b);

class Program
{
    static int Add(int x, int y) => x + y;

    static void Main()
    {
        Calculate calc = Add;
        Console.WriteLine(calc(3, 4));
    }
}

Delegate는 메서드 시그니처(반환형 + 파라미터)가 동일한 메서드만 참조할 수 있다.

Multicast Delegate


Calculate calc = Add;
calc += (a, b) => a * b;

int result = calc(2, 3);

여러 메서드를 연결할 수 있으며, 호출 순서는 등록 순서이다. 반환값은 마지막 메서드의 결과만 유지된다.

Func / Action

C#에서는 Delegate 선언을 줄이기 위해 Func, Action을 제공한다.


Func<int, int, int> add = (a, b) => a + b;
Action log = msg => Console.WriteLine(msg);

📘 Microsoft 공식 문서: Delegate 개요 - Microsoft Docs

 

C#에서 대리자 형식을 사용하는 방법 - C#

C#에서 대리자 형식을 탐색합니다. 대리자는 정의된 매개 변수 목록 및 반환 형식이 있는 메서드를 참조하는 날짜 형식입니다. 대리자를 사용하여 메서드를 다른 메서드에 인수로 전달합니다.

learn.microsoft.com

 


3️⃣ Event (이벤트)

Event는 Delegate를 외부에서 직접 호출하지 못하도록 캡슐화한 구조이다.

즉, 이벤트는:

  • 구독 가능
  • 발생은 클래스 내부에서만

Event 기본 예제


class Button
{
    public event Action Clicked;

    public void Click()
    {
        Clicked?.Invoke();
    }
}

class Program
{
    static void Main()
    {
        Button btn = new Button();
        btn.Clicked += () => Console.WriteLine("버튼 클릭됨");
        btn.Click();
    }
}

EventHandler 패턴


public event EventHandler OnChanged;

이 패턴은 .NET 표준 이벤트 설계 방식이며, WPF, WinForms, ASP.NET 내부에서도 동일하게 사용된다.

📘 Microsoft 공식 문서: .NET 이벤트 개요 - Microsoft Docs

 

이벤트 처리 및 이벤트 발생시키기 - .NET

대리자 모델을 기반으로 하는 .NET 이벤트를 처리하고 발생시키는 방법을 알아봅니다. 이 모델을 사용하면 구독자가 공급자에 등록하거나 공급자로부터 알림을 받을 수 있습니다.

learn.microsoft.com

 


4️⃣ Reflection + Delegate + Event의 조합

실무에서는 이 세 가지가 결합되어 사용된다.

  • Reflection → 메서드 탐색
  • Delegate → 메서드 바인딩
  • Event → 외부 알림

Reflection으로 Event 자동 연결


foreach (var method in type.GetMethods())
{
    if (method.Name.StartsWith("On"))
    {
        Delegate d = Delegate.CreateDelegate(typeof(Action), instance, method);
        d.DynamicInvoke();
    }
}

이런 구조는 프레임워크 자동 바인딩의 핵심 로직이다.


5️⃣ 성능 및 주의사항

  • Reflection은 느리다 → 캐싱 필수
  • Delegate 체인은 디버깅이 어렵다
  • Event 미해제 시 메모리 누수 발생
  • WeakEvent 패턴 고려

6️⃣ 마무리

Reflection, Delegate, Event는 단순 문법이 아니라 .NET 생태계 전체를 이해하는 열쇠이다.

이 개념들을 이해하면?

  • 프레임워크 내부 구조 이해
  • 라이브러리 설계 능력 향상
  • 면접 고급 질문 대응 가능

이라는 강력한 장점을 얻게 된다.

반응형