대리자와 이벤트

sz L·2023년 4월 12일
0

씨샵

목록 보기
11/17
post-thumbnail
post-custom-banner

대리자 선언

delegate int MyDelegate(int a, int b);

대리자

대리자는 메서드를 대신하여 호출하는 기법이다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace cs26_delegate
{
    // 대리자 사용하겠다는 선언
    delegate int CalcDelegate(int a, int b);

    delegate int Compare(int a, int b); // a와 b중에서 뭐가 큰지(작은지) 비교 대리자

    #region <대리자 기본>
    class Calc
    {
        public int Plus(int a, int b)
        {
            return a + b;
        }

        // static이 붙으면 무조건 실행될 때 최초 메모리에 올라감
        // 프로그램 실행중에는 언제든지 접근 가능
        public static int Minus(int a, int b)
        {
            return a - b;
        }

    }
    #endregion
    internal class Program
    {
        //오름차순 비교
        static int AscendCompare(int a, int b)
        {
            if (a > b) return 1;
            else if(a == b) return 0;
            else return -1;
        }
        //내림차순 비교
        static int DescendCompare(int a, int b)
        {
            if (a < b) return 1;
            else if (a == b) return 0;
            else return -1;
        }

        // 오름차순, 내림차순 정렬 하나의 메소드에서 다 실행 가능
        static void BubbleSort(int[] DataSet,Compare comparer)
        {
            int i = 0, j = 0, temp = 0;

            for(i=0;i<DataSet.Length; i++)
            {
                for (j=0;j<DataSet.Length-(i+1);j++)
                {
                    if (comparer(DataSet[j], DataSet[j+1]) > 0) // 대리자 사용
                    {
                        temp = DataSet[j + 1];
                        DataSet[j+1] = DataSet[j];
                        DataSet[j] = temp; //Swap
                    }
                }
            }
        }


        static void Main(string[] args)
        {
            #region < 대리자 기본 예>
            // 일반적으로 클래스 사용하는 방법 : 직접호출
            Calc normalCalc = new Calc();
            int x = 10, y = 15;
            
            int res = normalCalc.Plus(x, y);
            Console.WriteLine(res);
            Console.WriteLine(normalCalc.Plus(x, y));

            // class내 static은 Console.WriteLine(normalCalc.Minus(x, y));  안 된다
            res = Calc.Minus(x, y);
            Console.WriteLine(res);


            // 대리자를 사용하는 방식 : 대리자가 대신 실행
            x = 30; y = 20;
            Calc delCalc = new Calc();
            CalcDelegate Callback;

            Callback = new CalcDelegate(delCalc.Plus);
            // Calc.Plus() 대신 호출
            int res2 = Callback(x, y);
            Console.WriteLine("Delegate사용 : {0}", res2);
            
            Callback = new CalcDelegate(Calc.Minus);
            res2 = Callback(x, y);
            Console.WriteLine("Delegate사용 : {0}", res2);
            #endregion

            int[] origin = { 4, 7, 8, 2, 9, 1 };
            Console.WriteLine("오름차순 버블정렬");
            BubbleSort(origin , new Compare(AscendCompare));

            foreach(var item in origin)
            {
                Console.Write("{0}",item);
            }
            Console.WriteLine();
            Console.WriteLine("내림차순 버블정렬");
            BubbleSort(origin, new Compare(DescendCompare));
            foreach (var item in origin)
            {
                Console.Write("{0}", item);
            }
            Console.WriteLine();

        }
    }
}


대리자 체인

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace cs27_delegateChain
{
    delegate void ThereIsAFire(string location);    // 불났을 때 대신해주는 대리자

    delegate int Calc(int a, int b);

    delegate string Concatenate(string[] args);

    class Sample
    {
        private int valueA; //멤버변수 -> 외부에서 접근 불가

        public int ValueA   // 프로퍼티
        {
            /*get { return valueA;}
            set { valueA = value; }*/
            get => valueA;  // 람다식 
            set => valueA = value;
        }
    }

    internal class Program
    {
        #region <소방서>
        static void Call119(string location)
        {
            Console.WriteLine("소방서죠! {0}에 불났어요!!",location); 
        }
        static void ShoutOut(string location)
        {
            Console.WriteLine("{0}에 불났어요!",location) ;
        }
        static void Escape(string location)
        {
            Console.WriteLine("{0}에서 탈출합니다.", location);
        }
        #endregion

        static string ProcConcate(string[] args)
        {
            string result = string.Empty;
            foreach(string s in args)
            {
                result += s + "/";
            }
            return result;
        }
        static void Main(string[] args)
        {
            #region <대리자 체인>
            Console.WriteLine("--기본--");
            var loc = "우리집";
            Call119(loc);
            ShoutOut(loc);
            Escape(loc);
            
            // 대리자
            Console.WriteLine("\n--대리자(체인 연결)--");
            var otherloc = "경찰서";
            ThereIsAFire fire = new ThereIsAFire(Call119);
            fire += new ThereIsAFire(ShoutOut);
            fire += new ThereIsAFire(Escape);  // 대리자 메서드 연결(추가)
            fire(otherloc);
            
            Console.WriteLine("\n--대리자(체인 끊기)--");
            fire -= new ThereIsAFire(Escape);   // 대리자 메서드 끊기(삭제)
            fire("다른집");
            Console.WriteLine();

            // 익명함수
            Calc plus = delegate (int a, int b)
            {
                return a + b;
            };
            Console.WriteLine(plus(6, 7));

            Calc minus = (a, b) => { return a - b; };
            Console.WriteLine(minus(6, 7));

            Calc simpleMinus = (a, b) => a - b; //람다식
            #endregion

            #region <람다식 사용하기>
            Concatenate concat = new Concatenate(ProcConcate);
            var result = concat(args);
            Console.WriteLine(result);

            Console.WriteLine("람다식으로");
            Concatenate concat2 = (arr) =>
            {
                string res = string.Empty;
                foreach (string s in args)
                {
                    res += s + "/";
                }
                return res;
            };
            Console.WriteLine(concat2(args));
            #endregion
        }
    }
}


이벤트

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace cs28_event
{
    // delegate가 EventHandler 사용하기 위해서 만들었다고 생각하장
    // 이벤트를 사용하려면
    // 1. 대리자 생성
    delegate void EventHandler(string message);

    class CustomNotifier
    {

        // 2. 이벤트를 준비(대리자를 사용한)
        public event EventHandler SomeThingChanged;
        public void DoSomeThing(int number)
        {
            int temp = number % 10;

            if (temp != 0 && temp % 3 == 0)
            {
                // 3. 특별한 이벤트가 발생할 상황에서 이벤트를 수행
                SomeThingChanged(string.Format("{0} : odd", number));
            }
        }
    }
    internal class Program
    {
        // 4. 이벤트가 대신 호출할 메소드 구현
        static void CustomHandler(string message)
        {
            Console.WriteLine(message);
        }

        static void Main(string[] args)
        {
            CustomNotifier notifier = new CustomNotifier();

            // notifier에서 SomeThingChanged이벤트가 발생하면 EventHandler(대리자)에서 CustomHandler 가 대신 이벤트 처리해줌
            notifier.SomeThingChanged += new EventHandler(CustomHandler);
            for (int i = 0; i <= 30; i++)
            {
                notifier.DoSomeThing(i);
            }
        }
    }
}

profile
가랑비는 맞는다 하지만 폭풍은 내 것이야
post-custom-banner

0개의 댓글