C# Delegate vs Interface — 언제 무엇을 선택해야 하는가?
C#을 어느 정도 사용하다 보면 이런 고민을 하게 된다.
“이건 Delegate로 처리할까, Interface로 분리할까?”
이 질문에 대한 답은 문법이 아니라 설계 의도에 있다.
1️⃣ Delegate와 Interface의 본질적 차이
Delegate의 본질
Delegate는 행위(Behavior)를 전달하기 위한 도구다.
- 메서드를 값처럼 전달
- 콜백
- 이벤트 처리
- 일회성 로직 주입
Action logger = msg => Console.WriteLine(msg);
logger("Hello");
Interface의 본질
Interface는 역할(Role)과 계약(Contract)이다.
- 객체의 책임 정의
- 다형성
- 확장 가능한 구조
- 테스트 대체(Mock)
public interface ILogger
{
void Log(string message);
}
2️⃣ 구조적 관점 비교
| 항목 | Delegate | Interface |
|---|---|---|
| 목적 | 행위 전달 | 역할 정의 |
| 상태 보유 | 불가능 | 가능 |
| 확장성 | 낮음 | 높음 |
| 의존성 | 느슨함 | 명확함 |
| 테스트 대체 | 제한적 | 매우 쉬움 |
3️⃣ Delegate가 적합한 경우
① 단일 동작 콜백
void Execute(Action onCompleted)
{
// 작업 수행
onCompleted?.Invoke();
}
✔ 상태 없음 ✔ 한 가지 책임 ✔ 호출 타이밍만 중요
② 전략이 자주 바뀌는 경우
Func<int, int, int> calc = (a, b) => a + b;
calc = (a, b) => a * b;
③ LINQ / 이벤트 / 비동기 흐름
LINQ와 Event는 Delegate 없이는 성립하지 않는다.
📘 Microsoft 공식 문서: Delegate 개요
C#에서 대리자 형식을 사용하는 방법 - C#
C#에서 대리자 형식을 탐색합니다. 대리자는 정의된 매개 변수 목록 및 반환 형식이 있는 메서드를 참조하는 날짜 형식입니다. 대리자를 사용하여 메서드를 다른 메서드에 인수로 전달합니다.
learn.microsoft.com
4️⃣ Interface가 적합한 경우
① 상태(State)가 필요한 경우
public class FileLogger : ILogger
{
private readonly string _path;
public FileLogger(string path) => _path = path;
public void Log(string message)
{
File.AppendAllText(_path, message);
}
}
② 객체 수명 주기 관리
DI 컨테이너는 Interface 없이는 설계가 불가능하다.
③ 테스트 / Mocking
var mockLogger = new Mock();
📘 Microsoft 공식 문서: Interface 개요
인터페이스 - 여러 형식에 대한 동작 정의 - C#
C#의 인터페이스에는 비추상 클래스 또는 구조체에서 구현해야 하는 관련 기능 그룹에 대한 정의가 포함되어 있습니다. 인터페이스를 구현하는 형식에 대한 멤버와 해당 서명을 지정합니다.
learn.microsoft.com
5️⃣ 잘못된 선택 사례 (안티 패턴)
❌ Interface 남용
public interface IOnClickHandler
{
void OnClick();
}
→ 단순 이벤트라면 Delegate가 더 적합
❌ Delegate 남용
Action save;
Action load;
Action delete;
→ 역할이 명확하면 Interface가 맞다
6️⃣ 혼합 패턴: Interface + Delegate
실무에서는 둘을 함께 사용한다.
public interface IRepository
{
void Save(Action onCompleted);
}
Interface는 구조를 정의하고, Delegate는 흐름을 유연하게 만든다.
7️⃣ 설계 기준 요약
- 행위 하나 → Delegate
- 역할 정의 → Interface
- 상태 필요 → Interface
- 콜백 / 이벤트 → Delegate
- DI / 테스트 → Interface
8️⃣ 마무리
Delegate와 Interface는 경쟁 관계가 아니다.
문제의 성격이 다를 뿐이다.
이 차이를 이해하면?
- 코드가 단순해지고
- 확장이 쉬워지며
- 프레임워크 구조가 보이기 시작한다
'C#' 카테고리의 다른 글
| DI 컨테이너 직접 구현하기 - Reflection 종합편 (0) | 2026.02.16 |
|---|---|
| Event 메모리 누수와 WeakEvent 패턴 완전 분석 (0) | 2026.02.14 |
| C# Reflection 성능 최적화 - Expression Tree와 IL Emit (0) | 2026.02.10 |
| C# 비동기 / 병렬 처리 + GC 최적화 실전 가이드 (0) | 2026.02.08 |
| C# 개발자를 위한 고급 메모리 관리: GC를 넘어서 Span과 Memory까지 (0) | 2025.12.14 |