I'm FanJae.

[20260515] C# ( Action ) 본문

Unity/Unity 초격차캠프

[20260515] C# ( Action )

FanJae 2026. 5. 15. 18:39

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
Comments