상세 컨텐츠

본문 제목

[c# 키워드] delegate

C#

by 메타샤워 2023. 7. 18. 18:34

본문

C# deledate 는 C/C++의 함수 포인터와 비슷한 개념으로 메스드 입력 파라미터와 리턴 타입에 대한 정의를 한후,

동일한 입력 파라미터와 리턴 타입을 가진 메서드를 서로 호환해서 불러 쓸 수 있는 기능이다.

예를 들면, 아래 delegate는 입력 파라미터가 int 하나이고 리턴값이 없는 메서드를 가리킨다.

RunThis()메서드와 RunThat() 메서드는 모두 int 입력 하나에 리턴값이 없는 메서드이므로 , RunDelegate의 함수 형식 (protoType)과

맞으므로 이 delegate를 사용 할 수 있다.

 

using System;    
namespace MySystem    
{    
    class MyClass    
    {    
        // 1. delegate 선언    
        private delegate void RunDelegate(int i);    
    
        private void RunThis(int val)    
        {    
            // 콘솔출력 : 1024    
            Console.WriteLine("{0}", val);    
        }    
    
        private void RunThat(int value)    
        {    
            // 콘솔출력 : 0x400    
            Console.WriteLine("0x{0:X}", value);    
        }    
    
        public void Perform()    
        {    
            // 2. delegate 인스턴스 생성    
            RunDelegate run = new RunDelegate(RunThis);    
            // 3. delegate 실행    
            run(1024);    
    
            //run = new RunDelegate(RunThat); 을 줄여서     
            //아래와 같이 쓸 수 있다.    
            run = RunThat;    
    
            run(1024);    
        }    
    }    
    
    class Program    
    {    
        static void Main(string[] args)    
        {    
            MyClass mc = new MyClass();    
            mc.Perform();    
        }    
    }    
}

delegate를 메서드 파라미터로 전달

 
delegate는 동일한 함수  Prototype을 갖는 메서드를 가리키므로 함수의 포인터를 파라미터로 전달하듯, 
 
다른 함수의 파라미터로 사용될 수 있다. delegate 파라미터로 전달받은 쪽은 이를 자신의 내부 클래스 함수를 호출하듯 사용한다.
 
(C# delegate는 내부적으로 .Net Delegate/ MulticastDelegate 클래스를 사용한다. 따라서 이 클래스가 지원하는 
 
속성(Method - 함수 Prototype)과 메서드(GetInvokactionList() )를 모두 사용할 수 있다. )
 
아래 예제는 올림차순으로 비교한수 ( AscendingCompare) 와 내림차순으로 비교하는 함수 (DescendingCompare) 를 
 
delegate로 전달하여, 하나의 Sort메서드레서 비교함수에 따라 여러 개의 소트가 가능하다는것을 보여주는 예이다.
class MySort    
{    
    public delegate int CompareDelegate(int i1, int i2);    
    
    public static void Sort(int[] arr, CompareDelegate comp)    
    {    
        if (arr.Length < 2) return;    
        Console.WriteLine("함수 Prototype: " + comp.Method);    
    
        int ret;    
        for (int i = 0; i < arr.Length - 1; i++)    
        {    
            for (int j = i+1; j < arr.Length; j++)    
            {    
                ret = comp(arr[i], arr[j]);    
                if (ret == -1)    
                {    
                    // 교환    
                    int tmp = arr[j];    
                    arr[j] = arr[i];    
                    arr[i] = tmp;    
                }    
            }    
        }    
        Display(arr);    
    }    
    static void Display(int[] arr)    
    {    
        foreach (var i in arr) Console.Write(i + " ");    
        Console.WriteLine();    
    }    
}    
    
class Program    
{    
    static void Main(string[] args)    
    {    
        (new Program()).Run();    
    }    
    void Run()    
    {    
        int[] a = { 5, 53, 3, 7, 1 };    
            
        // 올림차순으로 소트    
        MySort.CompareDelegate compDelegate = AscendingCompare;    
        MySort.Sort(a, compDelegate);    
    
        // 내림차순으로 소트    
        compDelegate = DescendingCompare;    
        MySort.Sort(a, compDelegate);                
    }    
    int AscendingCompare(int i1, int i2)    
    {    
        if (i1 == i2) return 0;    
        return (i2 - i1) > 0 ? 1 : -1;    
    }    
    int DescendingCompare(int i1, int i2)    
    {    
        if (i1 == i2) return 0;    
        return (i1 - i2) > 0 ? 1 : -1;    
    }    
}

'C#' 카테고리의 다른 글

[C#] Interface로 구현한 폼 간 값전달  (0) 2023.07.18
[c# 키워드] Lambda Expression =>  (0) 2023.07.18
[c# 키워드] yield  (0) 2023.07.18
[C#] 마우스 후킹하기  (0) 2023.07.18
[C#] 키보드 후킹하기  (0) 2023.07.18

관련글 더보기