22.01.04 대리자 delegate

2022. 1. 4. 22:44C#/수업 내용

--------------------------본 블로그는 개인 공부 기록용이기에 잘못된 내용이 있을 확률 50000%------------------------

 

무명 함수란 말 그대로 이름이 없는 함수를 말한다.

간단한 메서드, 혹은 일회용으로 사용할 메서드를 delegate에 할당하기 위해 무명 함수를 사용하는 듯.

간단하고, 일회용이기에 따로 이름을 지정해주지 않아서 무명 함수 라고 하는 것 같다.

 

콜백 함수.

Call Back 의 뜻은 영어로 '회신하다', '다시 전화를 걸다', '답신 전화' 이다.

그 의미에 맞게 콜백 함수란, 

작업들을 받아 두었다가 어떤 이벤트가 발생했을 때, 실행되야 할 일련의 작업들을 '회신'한다. or 다시 돌려주는 기능을 말한다.

 

C#에서는 콜백함수를 구현하기 위해 delegate를 사용한다. 예를 들어

함수가 delegate타입으로 캐스팅되어 어떤 함수의 매개변수로 들어가거나,

함수가 delegate타입으로 소속되어 호출되거나 하는 것이다.

 

 

※ 오늘의 느낀 점 : 어떤 별개의 클래스에서 에러가 나도 나머지 클래스들은 정상 작동하도록 설계하자.

연쇄작용을 만들지 않기.

 

 

[퀘스트]

1) 중첩 클래스가 뭔지 조사하고 이해한다.

2) 무명 함수 사용을 실습한다.

https://www.csharpstudy.com/CSharp/CSharp-anonymous-method.aspx

 

C# 무명 메서드 - C# 프로그래밍 배우기 (Learn C# Programming)

C# 무명 메서드 (Anonymous Method) 앞의 C# delegate 예제를 보면 예제의 delegate들은 모두 이미 정의된 메서드를 가리키고 있었다. 이렇게 미리 정의된 메서드들과는 달리, C# 2.0에서부터 메서드를 미리

www.csharpstudy.com

3) 콜백 함수를 이해한다.

https://novlog.tistory.com/47

 

[C# 고급문법] #2 Delegate(델리게이트) & 콜백함수(CallBack)

[목차] #1. 콜백이란? #2.1 델리게이트(Delegate) 선언 #2.2 .Invoke() #2.3 델리게이트 체인(Delegate Chain) * 개인적인 공부 기록용으로 작성한 포스팅 이기에 잘못된 내용이 있을 수 있으며, 추가하거나 잘못

novlog.tistory.com

 

4) 대리자의 다양한 활용 사례를 참고하고 스스로 응용하여 숙달시키기.

 

 

이하 수업내용--------------------------------------------------------------------------------------

 

1) 함수가 delegate타입으로 캐스팅되어 어떤 함수의 매개변수로 들어가는 형태

using System;

namespace helloworldConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            new App2();
        }
    }
}

-----------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;

namespace helloworldConsoleApp1
{
    class Scv
    {
        public delegate void DelTest(int i);

        public Scv()
        {

        }

        public void Gather(DelTest DelegateMethod)
        {
            DelegateMethod(5);
        }
    }
}


-----------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;

namespace helloworldConsoleApp1
{
    class App2
    {
        public App2()
        {
            Scv scv = new Scv();
            scv.Gather(GatherMinerals);
        }

        public void GatherMinerals(int amount)
        {
            Console.WriteLine("{0}개의 미네랄을 수집했습니다.", amount);
        }
    }
}

결과

 

 

2) 함수가 delegate타입으로 소속되어 호출되는 형태

using System;

namespace helloworldConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            new App();
        }
    }
}

-----------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;

namespace helloworldConsoleApp1
{
    class Marine : Unit
    {
        public int hp;
        public int damage;

        public delegate void OnDieMarine();

        public OnDieMarine odm;
    }
}

-----------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;

namespace helloworldConsoleApp1
{
    class App
    {
        public App()
        {
            Console.WriteLine("앱 클래스 생성");

            Unit marine = new Marine("을");//hp 4
            marine.Init(new Position(2, 3));
            
            Unit zerg = new Zergling("갑");//damage 1
            zerg.Init(new Position(5, 5));
            
            Marine downCastedMarine = (Marine)marine;
            downCastedMarine.odm = new Marine.OnDieMarine(OnDie);
            downCastedMarine.odm += new Marine.OnDieMarine(OnDie);

            Marine.OnDieMarine oodm = OnDie;

            zerg.Attack(zerg, ref marine, "claw");
            zerg.Attack(zerg, ref marine, "claw");
            zerg.Attack(zerg, ref marine, "claw");
            zerg.Attack(zerg, ref marine, "claw");
            
            if(downCastedMarine.hp <= 0)
            {
                downCastedMarine.odm();
                oodm();
            }
        }

        public void OnDie()
        {
            Console.WriteLine("마린이 죽었습니다.");
        }
    }
}

결과

 

 

이하 예제 실습 기록-----------------------------------------------------------------------------------------

 

using System;
using System.Collections.Generic;
using System.Text;

namespace helloworldConsoleApp1
{
    class App
    {
        public App()
        {
            Barrack br = new Barrack();
            Marine mar = br.CreateSoldierUnit(br.CreateMarine, "첫번째 마린");
            mar.Init(new Position(2,2));
        }
    }
}

-----------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;

namespace helloworldConsoleApp1
{
    class Barrack
    {
        public delegate Marine DelCreateSoldierUnit(string name);

        public Marine CreateSoldierUnit(DelCreateSoldierUnit callback, string unitName)
        {
            return callback(unitName);
        }

        public Marine CreateMarine(string name)
        {
            return new Marine(name);
        }
    }
}

배럭에서 마린 만들기.

 

--------------------------------------

 

using System;
using System.Collections.Generic;
using System.Text;

namespace helloworldConsoleApp1
{
    class App
    {
        public App()
        {
            Nuclear nc = new Nuclear();
            nc.AlertMessages += nc.StartCountDown;
            nc.AlertMessages += new Nuclear.DelAlertMessage(nc.CountingSeconds);
            nc.AlertMessages += nc.NuclearLaunchDetected;
            nc.LaunchNuclearMissile();
        }
    }
}

-----------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;

namespace helloworldConsoleApp1
{
    class Nuclear
    {
        public delegate void DelAlertMessage();
        public DelAlertMessage AlertMessages;

        public void StartCountDown()
        {
            Console.WriteLine("Nuclear will be launched in 10 seconds.");
        }

        public void CountingSeconds()
        {
            for (int i = 10; i >= 0; i--)
            {
                Console.WriteLine(i);
            }
        }

        public void NuclearLaunchDetected()
        {
            Console.WriteLine("Nuclear launch detected.");
        }

        public void LaunchNuclearMissile()
        {
            AlertMessages();
        }
    }
}

핵 발사

 

배럭에서 마린 만들기는

선언한 delegate타입과 반환타입, 사용 인수가 같은 함수를 어떤 함수의 매개함수로 캐스팅한 사례이고,

 

핵 발사는

선언한 delegate타입과 반환타입, 사용 인수가 같은 함수를 선언한 delegate타입 변수 안에 넣어서 호출한 사레이다.