| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- BOJ
- Online Judge
- multi-thread
- git
- Toy Project
- Network Programming
- Data Structure
- PS
- 독서
- c#
- C++
- Unity
- System Programming
- Today
- Total
I'm FanJae.
[20260515] C# ( Action ) 본문
1. 정의
- Action은 C#에서 미리 제공하는 제네릭 델리게이트 타입이다.
- 반환값이 없는 void 메소드를 저장할 때 사용한다.
- 원래 delegate를 사용하기 위해서는 아래와 같이 정의를 해야했다.
public delegate void MyDelegate();
- 이러한 delegate를 간단하게 만들어서 사용할 수 있다.
Action myAction;
2. Action의 형태
Action -> void Method()
Action<int> -> void Method(int value)
Action<int, string> -> void Method(int value, string str)
- 즉, Action은 반환 타입이 void인 메서드만 담을 수 있다.
public static void PrintMessage()
{
Console.WriteLine("기본 메시지 출력");
}
Action action = PrintMessage;
action();
- 이 경우, action 은 매개변수가 없고, 반환값이 void인 메서드를 저장할 수 있다.
3. 필요한 이유
- Action을 사용하면 매번 직접 델리게이트를 선언하지 않아도 된다.
- 예를 들어, 아래와 같은 델리게이트를 직접 만들지 않아도 된다.
public delegate void StartAction();
public delegate void ItemAction(string itemName);
public delegate void RewardAction(int gold, string itemName);
- 아래와 같은 형태로 바로 사용이 가능하다.
Action startAction;
Action<string> itemAction;
Action<int, string> rewardAction;
- 즉 Action은 void 메소드를 저장하거나 전달할 때 사용하는 기본 델리게이트 타입이다.
4. 적용하지 않을 때 발생하는 문제
- Action을 사용하지 않으면 단순히 void 메서드를 전달하기 위해 매번 직접 델리게이트를 선언해야 하는 문제점이 있다.
public delegate void SceneLoadComplete();
public static void LoadScene(string sceneName, SceneLoadComplete onCompelete)
{
Console.WriteLine($"{sceneName} 로딩 시작...");
Console.WriteLine("로딩중...");
Console.WriteLine($"{sceneName} 씬 로딩 완료");
onComplete();
}
- 동작 자체는 문제가 없다. 하지만 간단한 콜백 하나를 위해 타입 선언이 계속 늘어난다.
- 반면 Action 을 사용하면, 다음처럼 조정이 가능하다.
public static void LoadScene(string sceneName, Action onComplete)
{
Console.WriteLine($"{sceneName} 로딩 시작...");
Console.WriteLine("로딩중...");
Console.WriteLine($"{sceneName} 씬 로딩 완료");
onComplete?.invoke();
}
5. 올바른 적용법 예시
① 콜백 구조를 사용한 Action의 적용 예시
internal class Program
{
public static void PrintMessage()
{
Console.WriteLine("기본 메시지 출력");
}
public static void ShowItemMessage(string itemName)
{
Console.WriteLine($"{itemName} 획득");
}
public static void ShowQuestReward(int gold, string itemName)
{
Console.WriteLine($"퀘스트 보상 : 골드 {gold}, 아이템 : {itemName}");
}
public static void PlayStartSound()
{
Console.WriteLine("시작 사운드 재생");
}
public static void ShowStartUI()
{
Console.WriteLine("시작 UI 표시");
}
public static void LoadScene(string sceneName, Action onComplete)
{
Console.WriteLine($"{sceneName} 로딩 시작...");
Console.WriteLine("로딩중...");
Console.WriteLine($"{sceneName} 씬 로딩 완료");
// onComplete가 null이 아니면 실행된다.
// 즉, 로딩이 끝난 뒤 외부에서 전달받은 메소드를 호출한다.
// 여기서는 콜백(Callback) 역할을 하게 된다.
onComplete?.Invoke();
}
static void Main()
{
Action action1 = PrintMessage;
action1();
Action<string> itemAction = ShowItemMessage;
itemAction("포션");
Action<int, string> rewardAction = ShowQuestReward;
rewardAction(500, "집행검");
Action gameStartAction = null;
// gameStartAction에 PlayerStartSound 메서드를 연결한다.
gameStartAction += PlayStartSound;
// gameStartAction에 ShowStartUI 메서드 추가 연결
gameStartAction += ShowStartUI;
// gameStartAction이 null이 아니면 연결된 메서드들을 순서대로 실행
gameStartAction?.Invoke();
LoadScene("마을씬", ShowStartUI);
}
}
② 콜백 구조에 대하여
public static void LoadScene(string sceneName, Action onComplete)
{
Console.WriteLine($"{sceneName} 로딩 시작...");
Console.WriteLine("로딩중...");
Console.WriteLine($"{sceneName} 씬 로딩 완료");
onComplete?.Invoke();
}
LoadScene("마을씬", ShowStartUI);
- LoadScene 이 씬 로딩을 담당한다.
- 씬 로딩이 끝난 뒤 실행할 메서드를 외부에서 전달 받는다.
- 여기서 ShowStartUI 가 콜백 메서드로 전달되는 것이다.
- 로딩이 완료 후 onComplete?.Invoke() 를 통해 실행된다.
6. 여러 메서드 연결
- Action도 델리게이트이다. 따라서 +=, -=와 같은 연산자를 사용해서 여러 메서드를 연결하거나 분리할 수 있다.
Action gameStartAction = null;
gameStartAction += PlaayStartSound;
gameStartAction += ShowStartUI;
gameStartAction?.Invoke();
7. 장점
- 직접 delegate 타입을 만들지 않아도 된다.
- void 메서드를 간단하게 저장할 수 있다.
- 메서드를 매개변수로 전달할 수 있다.
- 콜백 구조를 만들기 쉽다.
- +=, -=를 통해 여러 메서드를 연결하거나 제거하는 것이 가능하다.
- 이벤트, UI 버튼 클릭, 게임 로딩 완료 처리 같은 구조에 잘 맞는다.
8. 단점 / 주의점
① 반환값이 있는 메서드는 저장할 수 없다.
public static int GetGold()
{
return 100;
}
Action action = GetGold; // 불가능
- 반환값이 있는 메서드는 Func 를 사용해야 한다.
② 매개변수 형태가 정확히 맞아야 한다.
Action<int> action = ShowItemMessage; // 불가능
- ShowItemMessage는 string을 받는다. 따라서 아래처럼 작성해야 한다.
Action<string> action = ShowItemMessage;
③ null 체크가 필요하다.
Action action = null;
action(); // NullReferenceException이 발생한다.
action?.Invoke();
④ 너무 남용하면 코드 흐름을 추적하기 어렵다.
- Action은 메서드를 외부에서 전달 받기 때문에, 코드만 보고 실제 어떤 메서드가 실행되는지 바로 보이지 않는다.
LoadScene("마을씬",ShowStartUI);
9. 정리
- Action은 반환값이 없는 메서드를 저장하기 위해 C#에서 미리 제공하는 델리게이트 타입이다.
Action -> void Method()
Action<int> -> void Method(int)
Action<int, string) -> void Method(int, string)
- 다음과 같은 상황에서 자주 사용된다.
① 콜백 메서드 전달
② 버튼 클릭 후 실행할 동작 저장
③ 로딩 완료 후 실행할 함수 전달
④ 여러 void 메서드를 하나로 묶어 순서대로 실행
※ 즉, Action은 반환값이 없는 메서드를 변수처럼 저장하거나 다른 메서드에 전달하기 위한 기본 델리게이트 타입이다.
'Unity > Unity 초격차캠프' 카테고리의 다른 글
| [20260515] C# ( Event ) (0) | 2026.05.15 |
|---|---|
| [20260515] C# ( Func ) (0) | 2026.05.15 |
| [20260515] C# ( Delegate, 대리자 ) (0) | 2026.05.15 |
| [20260514] C# ( HashSet<T> ) (0) | 2026.05.14 |
| [20260514] C# ( Queue<T> ) (0) | 2026.05.14 |