[ 목차 ]
11일차 ! 곧 2주를 향해 다가간다.
이제 오늘을 마지막으로 C#에 대해 배우고,
내일부터는 유니티로 넘어간다.
오늘을 포함해 지금까지 배웠던 것을
이제 게임 만들면서 활용할 것이다. 벌써부터 기대중
그럼 마지막 C# 콘솔 공부 화이띵!!!
1. 델리게이트 (Delegate)
델리게이트(Delegate)는 메시지 출력을 위한 메서드 참조이다.
string 매개변수를 받고 반환값이 없는 void 메서드를 참조할 수 있는 타입이다.
class Program
{
delegate void MessageHandler(string message);
//델리게이트에 연결할 메서드
//메서드 형과 타입 이런 게 일치해야 받아줌
static void DisplayMessage(string message)
{
Console.WriteLine($"메시지: {message}");
}
static void DisplayUpperMessage(string message)
{
Console.WriteLine($"대문자 메시지: {message.ToUpper()}");
}
static void Main(string[] args)
{
Console.WriteLine("== 간단한 델리게이트와 이벤트 예제 ===");
//1. 델리게이트 사용해보기
Console.WriteLine("델리게이트1");
//델리게이트 변수 선어 및 메서드 연결
//DisplayMessage 메서드를 messageHandler 변수에 할당
MessageHandler messageHandler = DisplayMessage;
//델리게이트 호출 - 연결된 메서드가 실행됨
messageHandler("안녕하세요");
//델리게이트 다른 메서드 추가(멀티캐스트 델리게이트)
//+= 연산자로 메서드 추가
messageHandler += DisplayUpperMessage;
//여러 메서드가 연결된 델리게이트 호출
//등록된 모든 메서드가 순사대로 호출됨
Console.WriteLine("여러 메서드 호출: ");
messageHandler("Hello ");
}
}
호출 순서를 알아보자.
1번
Main에서 시작되는 것이니 기존 호출인 문자열을 출력하고,
2번
델리게이트 변수 선언 및 메서드에 연결한 것이 다음 실행이다.
변수에 displayMessage 메서드를 가져온다.
displayMessage는 (메시지: {message})이다.
3번
델리게이트를 호출한다.
(메시지: {message}) 여기에서 message가 "안녕하세요"로 적용되어
이 값이 4번으로 향해
메시지: 안녕하세요
이렇게 호출 된다.
5번
연산자로 메서드를 추가한다.
연결된 메서드가
6번으로 이동해
문자열을 하나 호출하고,
messageHandler("Hello ")
코드가 7번으로 이동해
메시지: Hello
이렇게 호출한다.
이 Hello 값을 8번으로 이동해
ToUpper()를 통해 대문자로 변환이 되어
대문자 메시지: HELLO
마지막인 호출을 하는 것이다.
2. 이벤트
이벤트는 특정 상황이 발생했을 때 알림을 보내는 것이다.
이벤트헨들러(EventHandler)는 C#에서 제공하는 기본 델리게이트 타입이다.
이벤트가 발생했을 때 실행될 메서드인 것이다.
아래의 예제를 통해 코드 실행 순서에 따라 자세하게 더욱 설명하겠다.
Charater 클래스에서
Name과 Health로 캐릭터의 이름과 체력을 저장하는 변수이다.
get만 수정이 가능하며, private set은 외부에서 수정할 수 없게 하였다.
아직 실행은 되지 않는다.
Program 클래스에서
Hero_OnDamaged 메서드 (이벤트 헨들러)가 정의된다.
아직 실행이 되지 않는다.
우선 Main 함수에서 실행을 시작하게 된다.
캐릭터 생성으로 Character 객체인 hero를 생성한다. (이름: "용사", 체력: 100)
+= 연산자를 통해
hero의 OnDamaged 이벤트에 Hero_OnDamaged 메서드를 등록한다.
"이벤트 알림: 용사가 데미지를 입었습니다!" 출력한다.
-= 연산자를 통해
.Hero_OnDamaged 메서드 이벤트 구독을 취소한다.
그래서 이벤트가 발생해도 호출되지 않는다.
//게임 캐릭터 클래스
class Character
{
//속성
public string Name { get; private set; }
public int Health { get; private set; }
//이벤트 정의 - 캐릭터가 데미지를 입었을 때 발생
//EventHandler는 C#에서 제공하는 기본 델리게이트 타입
//이벤트는 외부에서 직접 호출할 수 없고, +=와 -= 연산자로만 접근 가능
public event EventHandler OnDamaged;
//생성자
public Character(string name, int health)
{
Name = name;
Health = health;
}
//데미지를 입는 메서드
public void TakeDamage(int amount)
{
Health -= amount;
Console.WriteLine($"{Name}가 {amount}의 데미지를 입었습니다. 남은체력: {Health}");
//이벤트 발생 (구독자가 있는 경우에만)
//?. 연산자 OnDamaged가 null이 아닐 때만 invoke 메서드 호출
//EventArgs.Empty는 추가 데이터가 없을 때 사용하는 빈 이벤트 인자
OnDamaged?.Invoke(this, EventArgs.Empty);
}
}
class Program
{
//이벤트 핸들러 메서드
//EventHandler 델리게이트와 일치하는 시그니처를 가져야함
//sender: 이벤트를 발생시킨 객체 (여기서는 Character 객체)
//e: 이벤트와 관련된 추가 데이터(여기서는 사용하지 않음)
static void Hero_OnDamaged(object sender, EventArgs e)
{
//sender를 character 타입으로 형변환
Character character = (Character)sender;
Console.WriteLine($"이벤트 알림: {character.Name}가 데미지를 입었습니다! "
+ $"현재 체력: {character.Health}");
}
static void Main(string[] args)
{
//캐릭터 생성
Character hero = new Character("용사", 100);
//이벤트 구독 +=
//이벤트가 발생했을 때 실행될 메서드 등록
hero.OnDamaged += Hero_OnDamaged;
//데미지 입히기
//TakeDamage 메서드 내에서 OnDamaged 이벤트가 발생함
hero.TakeDamage(30);
//이벤트 구독 취소 -=
//더이상 이벤트 발생시 메서드가 호출되지 않음
hero.OnDamaged -= Hero_OnDamaged;
Console.WriteLine("이벤트 구독 취소 ");
hero.TakeDamage(20);
}
}
드디어 마지막 콘솔 공부가 끝이났다.
11일이라는 숫자만 봐서는 짧게 느껴지지만,
대략 2주에 걸쳐 배웠다.
고생했다 . . . . . .
다음에 있을 유니티도 힘내ㅈ ㅏ.. . . .