본문 바로가기
전공/C# 프로그래밍

16강. 대리자와 이벤트 (1)

by 임 낭 만 2023. 6. 14.

형식으로의 대리자

대리자 (delegate)

  • 대리자는 메서드에 대한 참조
    • 참고로, “참조”라는 용어는 객체의 주소를 가리키는 것을 의미
    • 대리자에 메소드의 주소를 할당한 후 대리자를 호출하면 이 대리자가 메소드를 호출
  • 대리자는 delegate 키워드를 이용해서 선언
    • 클래스를 선언하는 위치와 같은 위치라면 어디든지 선언할 수 있음

형식(type)으로의 대리자

  • 대리자는 인스턴스가 아닌 데이터 형식(type)
    • 메소드를 참조하기 위해 대리자의 인스턴스를 생성하여 사용
    • 대리자의 인스턴스는 메서드를 참조

대리자 인스턴스 생성부터 호출까지

  • 이전 슬라이드의 사용예제를 통한 설명 :
    • Callback은 반환 형식이 int, 매개변수가 (int, int)인 MyDelegate 대리자 인스턴스
    • MyDelegate() 생성자 호출해서 Callback 인스턴스 생성
    • 생성자의 인수로 Plus() 또는 Minus()를 사용하여 Callback이 해당 메서드를 참조하게 만듦
    • 메서드 호출하듯이 Callback을 사용하면 현재 참조하는 메서드를 실행하여 결과를 반환

using System;

namespace Delegate
{
    delegate int MyDelegate( int a, int b);
    class Calculator
    {
        public int Plus(int a, int b)	//인스턴스 메서드
        {
            return a + b;
        }
        public static int Minus(int a, int b)	//정적 메서드
        {
            return a - b;
        }
    }
    class MainApp
    {
        static void Main(string[] args)
        {
            Calculator Calc = new Calculator();
            MyDelegate Callback;
			//인스턴스 메서드 참조
            Callback = new MyDelegate( Calc.Plus );
            Console.WriteLine(Callback(3, 4));
			//정적 메서드 참조
            Callback = new MyDelegate(Calculator.Minus);
            Console.WriteLine(Callback(7, 5));
        }
    }
}


대리자의 활용

대리자의 활용

  • 대리자는 메서드를 매개변수로 넘기기 위해 사용
    • 예를 들어, 배열을 정렬하는 메서드에서 비교 메서드를 매개변수로 받는 경우
    • 매개변수로 전달받은 비교 메서드에 따라 오름차순 정렬인지 내림차순 정렬인지 결정됨
  • 대리자를 사용해 비교 메서드를 매개변수로 받는 버블정렬 메서드 작성

  • 대리자를 사용해 비교 메서드를 매개변수로 받는 버블정렬 메서드 작성

  • 대리자를 사용해 비교 메서드를 매개변수로 받는 버블정렬 메서드 작성

using System;

namespace UsingCallback
{
    delegate int Compare(int a, int b);

    class MainApp
    {
        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; 
            int j = 0; 
            int temp = 0; 
 
            for ( i=0; i<DataSet.Length-1; 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; 
                    }
                }
            }
        }
        static void Main(string[] args)
        {
            int[] array = { 3, 7, 4, 2, 10 };

            Console.WriteLine("Sorting ascending...");
            BubbleSort(array, new Compare(AscendCompare));

            for (int i = 0; i<array.Length; i++)
                Console.Write($"{array[i]} ");

            int[] array2 = { 7, 2, 8, 10, 11 };
            Console.WriteLine("\nSorting descending...");
            BubbleSort(array2, new Compare(DescendCompare));            

            for (int i = 0; i < array2.Length; i++)
                Console.Write($"{array2[i]} ");

            Console.WriteLine();
        }
    }
}


일반화 대리자

  • 대리자는 일반화 메서드도 참조 가능
    • 대리자도 형식 매개변수를 이용하여 선언 (일반화 대리자)

using System;

namespace GenericDelegate
{
    delegate int Compare<T>(T a, T b);
    class MainApp
    {
        static int AscendCompare<T>(T a, T b) where T : IComparable<T>
        {
            return a.CompareTo(b);
        }
        static int DescendCompare<T>(T a, T b) where T : IComparable<T>
        {
            return a.CompareTo(b) * -1;
            // -1을 곱하면 자신보다 큰 경우 1,
			// 작은 경우 -1 반환
        }
        static void BubbleSort<T>(T[] DataSet, Compare<T> Comparer)
        {
            int i = 0;
            int j = 0;
            T temp;

            for (i = 0; i < DataSet.Length - 1; 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;
                    }
                }
            }
        }
        static void Main(string[] args)
        {
            int[] array = { 3, 7, 4, 2, 10 };

            Console.WriteLine("Sorting ascending...");
            BubbleSort<int>(array, new Compare<int>(AscendCompare));

            for (int i = 0; i < array.Length; i++)
                Console.Write($"{array[i]} ");

            string[] array2 = { "abc", "def", "ghi", "jkl", "mno" };
            Console.WriteLine("\nSorting descending...");
            BubbleSort<string>(array2, new Compare<string>(DescendCompare));

            for (int i = 0; i < array2.Length; i++)
                Console.Write($"{array2[i]} ");
        }
    }
}

댓글