Search

Delegate, event Action, Func

class
구조
상태
완료
날짜
목차

C#의 이벤트 처리 방식

유니티 C#에서는 여러 가지 함수들을 하나의 변수에 저장한 뒤, 처리하는 이벤트 처리 방식이 있습니다.
이러한 기능을 구현하기 위해 주로 사용되는 것은 Delegate입니다. Delegate는 메서드 참조를 위한 타입으로, 한 개 이상의 메서드를 참조할 수 있습니다. 이를 통해 다양한 함수를 하나의 델리게이트 변수에 저장하여 관리할 수 있으며, 필요한 시점에 호출할 수 있습니다.

Delegate

Delegate는 하나 이상의 메서드를 참조할 수 있는 타입입니다.
델리게이트를 사용하면 메서드를 변수에 할당하고, 다른 메서드로 전달하거나, 다른 객체의 메서드를 호출할 수 있습니다

Delegate의 선언과 사용

public delegate int Operation(int x, int y); public int Add(int x, int y) { return x + y; } public int Multiply(int x, int y) { return x * y; } Operation op = new Operation(Add); int result = op(5, 3); // 결과는 8 op = Multiply; result = op(5, 3); // 결과는 15
C#
복사

event

event 키워드는 특별한 유형의 델리게이트입니다.
이 키워드를 사용하여 클래스나 구조체에서 특정 상황이 발생했을 때 이를 알리는 이벤트를 정의할 수 있습니다.
이벤트는 클래스의 인터페이스의 일부로, 클래스 외부에서 이벤트 핸들러를 추가하거나 제거할 수 있도록 하지만, 이벤트를 직접 발생시킬 수는 없습니다.

event 키워드의 기능

캡슐화 : 이벤트는 클래스 외부에서 이벤트를 직접 발생시킬 수 없게 하여, 클래스의 책임과 기능을 명확히 분리합니다.
구독 관리 : 클래스 외부의 코드는 이벤트에 대해 구독(+=)하거나 구독 취소(=)할 수 있으나, 이벤트 리스트를 직접 수정할 수는 없습니다. 이를 통해 클래스의 내부 구현을 숨기고 오용을 방지할 수 있습니다.
public delegate void HealthChangedHandler(int newHealth); public class Player { public event HealthChangedHandler HealthChanged; private int health; public int Health { get { return health; } set { if (health != value) { health = value; OnHealthChanged(health); } } } protected virtual void OnHealthChanged(int newHealth) { HealthChanged?.Invoke(newHealth); } } public static void Main() { Player player = new Player(); player.HealthChanged += Player_HealthChanged; player.Health = 100; // 이벤트가 발생하고, 핸들러가 호출됩니다. // 이벤트 구독 취소 player.HealthChanged -= Player_HealthChanged; // 시도: 이벤트 핸들러 리스트를 직접 수정하려 함 - 이것은 불가능하며 컴파일 오류 발생 player.HealthChanged = new EventHandler(Player_HealthChanged); // 컴파일 오류 발생 } private static void Player_HealthChanged(int newHealth) { Console.WriteLine("Player's health changed to: " + newHealth); }
C#
복사
실질적으로 이벤트는 코드 컨벤션, 즉 코딩 규칙을 강제하는 것과 같습니다. 일반적으로 delegate와 같은 이벤트는 private로 선언하여 외부에서 접근할 수 없도록 만들고, 함수로만 추가 삭제를 할 수 있습니다. 이것을 간편하게 만든 것이 바로 이벤트입니다.

Action

Action은 델리게이트의 한 형태로, 특별히 반환 값이 없는 메서드(즉, void 반환 타입)를 참조하는 데 사용됩니다.
Action 델리게이트는 0개에서 16개의 매개 변수를 가질 수 있으며, 사용하는 매개 변수의 타입에 따라 Action<T>, Action<T1, T2>, ... Action<T1, T2, ..., T16>과 같이 선언할 수 있습니다.

Action 사용

Action printMessage = () => Console.WriteLine("Hello, Action!"); printMessage(); // 출력: Hello, Action! Action<int, int> printSum = (a, b) => Console.WriteLine($"The sum is: {a + b}"); printSum(5, 3); // 출력: The sum is: 8 public class EventPublisher { public event Action OnCustomEvent; public void TriggerEvent() { OnCustomEvent?.Invoke(); } } public static void Main() { var publisher = new EventPublisher(); publisher.OnCustomEvent += () => Console.WriteLine("Custom event triggered!"); publisher.TriggerEvent(); // 출력: Custom event triggered! } public static void ExecuteAction(Action action) { Console.WriteLine("Before action"); action(); Console.WriteLine("After action"); } public static void Main() { Action myAction = () => Console.WriteLine("Action executed"); ExecuteAction(myAction); // 출력: Before action, Action executed, After action }
C#
복사

Func

Func 델리게이트는 반환 값을 포함하는 메서드를 참조하는 데 사용되는 델리게이트 유형입니다.
Func는 0개에서 16개의 매개 변수를 가질 수 있으며, 마지막 제네릭 타입은 델리게이트가 반환하는 값의 타입을 나타냅니다.

Func의 사용

Func<string> greet = () => "Hello, World!"; Console.WriteLine(greet()); // 출력: Hello, World! Func<int, int, int> add = (x, y) => x + y; // 마지막 int가 반환값 Console.WriteLine(add(5, 3)); // 출력: 8 List<int> numbers = new List<int> { 1, 2, 3, 4, 5 }; var evenNumbers = numbers.Where(x => x % 2 == 0).ToList(); // Where문 자체가 Func<T,bool> 이랑 같음. 즉, numbers의 각 요소마다 bool값을 반환하는 함수. evenNumbers.ForEach(x => Console.WriteLine(x)); // 출력: 2, 4 public static void PrintResult(Func<int> operation) { Console.WriteLine($"Result: {operation()}"); } PrintResult(() => 42); // 출력: Result: 42 Func<Task<string>> fetchData = async () => { await Task.Delay(1000); // 1초 대기를 시뮬레이션 return "Data fetched"; }; var data = fetchData(); Console.WriteLine(data.Result); // 출력: Data fetched
C#
복사