【 C# 이벤트와 델리게이트: Func과 Action 】
1. 개요
- 이벤트(Event): 특정 동작이나 상태의 변화를 나타내는 것. 사용자 인터페이스, 시스템 알림 등에서 자주 사용.
- 델리게이트(Delegate): 메서드 참조를 저장하고 호출할 수 있는 타입. 메서드 포인터와 유사한 기능을 제공.
2. 이벤트와 델리게이트의 차이
이벤트:
- 주로 UI, 시스템 이벤트 등에서 사용.
- event 키워드를 사용하여 선언.
- 이벤트 핸들러는 델리게이트를 기반으로 하며, 이벤트는 해당 델리게이트를 통해 발생.
public class Alarm
{
public event Action OnAlarm;
public void TriggerAlarm()
{
OnAlarm?.Invoke();
}
}
델리게이트:
- 메서드를 캡슐화하여, 런타임에 메서드를 동적으로 호출.
- 직접 인스턴스화하여 사용할 수 있음.
public delegate void Notify(string message);
public class Notifier
{
public Notify notificationDelegate;
public void Notify(string message)
{
notificationDelegate?.Invoke(message);
}
}
3. 실무에서의 응용
이벤트 시스템 설계: UI 프레임워크에서 버튼 클릭, 마우스 움직임 등의 이벤트를 관리.
public class Button
{
public event Action OnClick;
public void Click()
{
OnClick?.Invoke();
}
}
동적 메서드 호출: 플러그인 시스템이나 다양한 알고리즘을 실행할 때 사용.
public class Calculator
{
// Func 델리게이트는 두 개의 int를 입력으로 받아 int를 반환하는 메서드를 참조할 수 있습니다.
public Func<int, int, int> calculationDelegate;
// Calculate 메서드는 델리게이트를 호출하여 계산을 수행합니다.
public int Calculate(int a, int b)
{
if (calculationDelegate != null)
{
return calculationDelegate(a, b);
}
else
{
throw new InvalidOperationException("Calculation method not set.");
}
}
}
public class Program
{
public static void Main()
{
Calculator calculator = new Calculator();
// 덧셈 계산 방법을 델리게이트에 할당합니다.
calculator.calculationDelegate = (a, b) => a + b;
Console.WriteLine("Addition: " + calculator.Calculate(3, 4)); // 출력: 7
// 뺄셈 계산 방법을 델리게이트에 할당합니다.
calculator.calculationDelegate = (a, b) => a - b;
Console.WriteLine("Subtraction: " + calculator.Calculate(10, 3)); // 출력: 7
// 곱셈 계산 방법을 델리게이트에 할당합니다.
calculator.calculationDelegate = (a, b) => a * b;
Console.WriteLine("Multiplication: " + calculator.Calculate(5, 6)); // 출력: 30
// 나눗셈 계산 방법을 델리게이트에 할당합니다.
calculator.calculationDelegate = (a, b) => a / b;
Console.WriteLine("Division: " + calculator.Calculate(20, 4)); // 출력: 5
}
}
4. 일반적인 실수와 해결 방안
메모리 누수: 이벤트 핸들러를 등록하고 해제하지 않을 경우 발생.
- 해결 방안: 이벤트 핸들러 등록과 해제를 철저히 관리.
button.OnClick += Button_Click;
button.OnClick -= Button_Click;
* 메모리 누수(Memory Leak)는 프로그램이 더 이상 필요하지 않은 메모리를 계속해서 점유하고 있어 메모리가 해제되지 않는 현상입니다. 이는 특히 장기 실행 애플리케이션에서 심각한 문제를 일으킬 수 있습니다.
델리게이트 호출 시 null 체크: 델리게이트 인스턴스가 null일 경우 예외 발생 가능.
- 해결 방안: ?.Invoke 연산자를 사용하여 안전하게 호출.
notificationDelegate?.Invoke("Message");
* 에러 내용
5. 디자인 패턴
옵저버 패턴(Observer Pattern):
- 객체의 상태 변화를 관찰하고, 상태 변화가 있을 때 자동으로 통지.
- 델리게이트와 이벤트를 활용하여 구현.
public class Subject
{
public event Action OnChange;
private int _state;
public int State
{
get => _state;
set
{
_state = value;
OnChange?.Invoke();
}
}
}
public class Observer
{
public void Subscribe(Subject subject)
{
subject.OnChange += () => Console.WriteLine("State changed!");
}
}
커맨드 패턴(Command Pattern):
- 요청을 캡슐화하여 호출자와 수행자를 분리.
- Func 또는 Action 델리게이트를 사용하여 구현.
public class Command
{
private readonly Action _execute;
public Command(Action execute)
{
_execute = execute;
}
public void Execute()
{
_execute();
}
}
public class Invoker
{
private Command _command;
public void SetCommand(Command command)
{
_command = command;
}
public void ExecuteCommand()
{
_command?.Execute();
}
}
전략 패턴(Strategy Pattern):
- 행위를 캡슐화하여 교환 가능하게 만들기.
- Func 델리게이트를 사용하여 구현.
public class Context
{
private Func<int, int, int> _strategy;
public void SetStrategy(Func<int, int, int> strategy)
{
_strategy = strategy;
}
public int ExecuteStrategy(int a, int b)
{
return _strategy(a, b);
}
}
'개발💻 > C#' 카테고리의 다른 글
[C#] Coupling, Cohesion 1 (0) | 2024.08.10 |
---|---|
[C#] Observer Pattern 1 (0) | 2024.07.13 |
[C#] Delegate 1 (0) | 2024.06.08 |
[C#] Using 지시문 (2) | 2022.08.24 |
[C#] Namespace (0) | 2022.08.23 |