반응형

델리게이트(delegate)의 문제
- 추가 연산(+=)을 하려고 했는데, 할당 연산(=)을 하는 경우 이전에 추가했던 함수 리스트들이 사라지는 문제
- 외부에서 접근제한이 없다면 함수와 같이 호출이 가능하게 된다.

위와 같은 문제를 해결하기 위해 event를 사용합니다.
이벤트(event)는 외부에서 추가나 차감 연산만 가능합니다.
이벤트(event)는 외부에서 직접 호출이 아닌 함수를 통한 호출을 해야합니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    delegate void Print(string strContent);
    class AAA
    {
        public event Print print;
 
        public void DelegatePrintAAA1(string strContent)
        {
            Console.WriteLine("AAA1" + strContent);
        }
        public void DelegatePrintAAA2(string strContent)
        {
            Console.WriteLine("AAA2" + strContent);
        }
        public void DelegatePrintAAA3(string strContent)
        {
            Console.WriteLine("AAA3" + strContent);
        }
 
        public void totalOutput()
        {
            if (this.print != null)
            {
                print("11111");
            }
        }
    }
    class Program
    {
        static void DelegatePrint(string strContent)
        {
            Console.WriteLine("normal" + strContent);
        }
 
        static void Main(string[] args)
        {
            AAA aaa = new AAA();
            aaa.print += aaa.DelegatePrintAAA1;
            aaa.print += aaa.DelegatePrintAAA2;
            //aaa.print = aaa.DelegatePrintAAA3; error 발생
            //aaa.print("111111"); error 발생
            aaa.totalOutput();
 
            aaa.print -= aaa.DelegatePrintAAA1;
            aaa.totalOutput();
        }
    }
}
 
 
 

이 예제에서 확인해봤을때 할당 연산이나 직접호출은 불가능합니다.

반응형

'개발공부 > C#' 카테고리의 다른 글

[C#] 제네릭  (0) 2019.10.19
[C#] 인덱서(Indexer)  (0) 2019.10.18
[C#] delegate  (0) 2019.10.16
[C#] Event  (0) 2019.10.15
[C#] yield  (0) 2019.10.14
반응형

특정 매개 변수와 반환 형식을 가진 함수에 대한 참조를 나타내는 형식을 말합니다.
delegate는 함수에 변수나 클래스를 인수로 전달하는 것과 같이 함수를 인수로 전달하는데 사용됩니다.
접근 가능한 클래스 또는 delegate형식과 일치하는 구조를 가진 모든 메서드는 대리자로 할당할 수 있습니다.
함수는 정적 함수거나 인스턴스 함수일 수 있습니다.

속성
- C++ 함수 포인터와 유사하지만 C++ 함수 포인터와 달리 어느 클래스 함수에서도 쉽게 할당 가능합니다.
- delegate는 함수 매개 변수로 전달이 가능합니다.
- delegate를 통해 콜백 함수를 정의할 수 있습니다.
- 여러 delegate를 연결 할 수 있습니다.

형식
public delegate 반환타입 함수명(매개 변수);
ex) public delegate void print(string strContent)


예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
 
    class Program
    {
        public delegate void Print(string strContent);
        static void DelegatePrint(string strContent)
        {
            Console.WriteLine(strContent);
        }
        
        static void Main(string[] args)
        {
            Print print = DelegatePrint;
 
            print("output1");
        }
    }
}
 
 



이렇게 간단하게 연결해서 사용할 수 있다.

1. 콜백함수
또한 매개변수로 전달하여 함수내에서 delegate를 호출할 수도 있습니다.
이렇게되면 동일한 함수안에 함수를 손쉽게 넣을 수 있게 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
 
    class Program
    {
        public delegate void Print(string strContent);
        static void DelegatePrint(string strContent)
        {
            Console.WriteLine(strContent);
        }
 
        static void Callback(Print callbackprint)
        {
            callbackprint("output2");
        }
        
        static void Main(string[] args)
        {
            Print print = DelegatePrint;
            // delegate를 매개변수로 넣습니다.
            Callback(print);
        }
    }
}
 
 



2. 멀티캐스트
대리자는 호출 시 둘 이상의 메서드를 호출할 수 있습니다.
더 추가하려는 경우 더하기 또는 더하기 대입 연산자('+' 또는 '+=')를 사용할 수 있으며,
추가된 메서드를 제거하기위해서는 빼기 또는 빼기 대입연산자('-' 또는 '-=')를 사용할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    class AAA
    {
        public void DelegatePrintAAA1(string strContent)
        {
            Console.WriteLine("AAA1" + strContent);
        }
        public void DelegatePrintAAA2(string strContent)
        {
            Console.WriteLine("AAA2" + strContent);
        }
    }
    class Program
    {
        public delegate void Print(string strContent);
        static void DelegatePrint(string strContent)
        {
            Console.WriteLine("normal" + strContent);
        }
        
        static void Main(string[] args)
        {
            AAA aaa = new AAA();
            Print print = new Print(DelegatePrint);
            print += aaa.DelegatePrintAAA1;
            print += aaa.DelegatePrintAAA2;
            print("++");
 
            print -= aaa.DelegatePrintAAA1;
            print -= aaa.DelegatePrintAAA2;
            print("--");
        }
    }
}
 
 

3. 범용성
제너릭 <T>를 이용해서 어떤 변수형에 상관없이 구현할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    delegate T calcDelegate<T>(T num1, T num2);
    
    class Program
    {
        static int addint(int num1, int num2)
        {
            return num1 + num2;
        }
 
        static float addfloat(float num1, float num2)
        {
            return num1 + num2;
        }
 
        public static void Calc<T>(T num1, T num2, calcDelegate<T> calc)
        {
            Console.WriteLine(calc(num1, num2));
        }
 
        static void Main(string[] args)
        {
            calcDelegate<int> addint1 = new calcDelegate<int>(addint);
            calcDelegate<float> addfloat2 = new calcDelegate<float>(addfloat);
 
            Calc(89, addint1);
            Calc(9.7f, 10.8f, addfloat2);
        }
    }
}
 
s
반응형

'개발공부 > C#' 카테고리의 다른 글

[C#] 인덱서(Indexer)  (0) 2019.10.18
[C#] 이벤트(event) & 델리게이트(delegate)  (0) 2019.10.17
[C#] Event  (0) 2019.10.15
[C#] yield  (0) 2019.10.14
[C#] 반복문  (0) 2019.10.13

+ Recent posts