본문 바로가기
[ Program ]/c#스터디

52. 델리게이트

by 관이119 2022. 2. 5.

앞에서 쓰레드의 가장기본적인 형태를 배웠다.

그런데 이쓰레드들을 사용할때 추가적으로 알아야 할것들이 많다.

일단 델리게이트부터 살펴보자.

 

델리게이트는 함수를 대신 호출해주는것 이라고 생각하면 된다.

함수를 직접호출하면 되지 왜 대신 호출하는게 필요할까 생각할 수 있다.

대부분의 경우 디커플링때문에 필요하다.

잘이해하기 힘든데 우리가 매번사용하는 버튼클릭이벤트를 한번생각해보자.

이벤트는 델리게이트를 랩핑한 클래스인데 일단 델리게이트와 이벤트는 같다고 생각하고 흐름을 따라가보자.

 

그림1

 

그림1은 우리가 자주 사용하는 기본 버튼클릭형태의 소스이다.

저기서 button1_Click 를 우클릭해서 모든참조찾기를 눌러보자.

그러면 그림1의 아래 부분에 있는 내용이 나온다.

저기서  this.button1.Click += new System.EventHandler(this.button1_Click);.....   이라고 되있는 라인을 더블클릭해보자.

 

그림2

 

그러면 그림2와 같이 디자인 화면으로 들어가지는데 여기서 위에 선택된 라인을 보자. ( 디자인화면은 나중에 따로 또 살펴보자.)

this.button1.Click += new System.EventHandler(this.button1_Click);

우리는 이코드를 만들지않았지만 자동으로 만들어져 있다.

이코드가 이벤트이다.

버튼을 클릭했을때 button1_Click 이라는 함수를 호출해주겠다, 내부내용은 직접 알아서 만들어라 이런내용이다.

당연히 버튼클릭했을때 실행할 내용까지 이벤트 측에서 정해줄수는 없다.(고정된 내용이라면 해당함수를 직접호출 해도되긴한다.)

위처럼 만들어진 상태라면 클릭이벤트와 button1_Click 함수사이의 관계는 아주 느슨하다.

각자가 뭘하는지 상관없이 연결되있기만 한상태인것이다.

이런상태를 디커플링상태라고한다.

그래서 이렇게 서로 신경쓰지않고 작동해야 할때 델리게이트(이벤트) 가 필요한것이다.

 

일단 이렇게까지만 생각하고 기본코드를 살펴보자.

 

그림3

 

그림3에 기본적인 사용법을 적어놨다.

클래스 맴버필드 위치에 델리게이트를 배치해야한다는것도 기억하자.

delegate string testdel(string s); 

string 형태를 반환하고 string 을 변수로 받는 함수를 대리호출하는 델리게이트를 추가했다.

그리고 버튼 클릭시 testdel 형태를 가지고 callfunc 함수를 호출하는 델이게이트 인스턴스를 생성하고 파라미터로 aaaa 를 넣어주면서 호출하고 리턴받은 내용을 출력했다.

잘 이해가 안되면 위에 설명한 내용을 천천히 여러번 읽어 보자.

 

 

그림4

 

그림4를 보면 다른 예제를 올려놨다.

하나의 함수가 여러 형태의 역할을 하는 예제이다.

cal 이라는 함수에서 calc 라는 형식의 델리게이트를 파라미터로 받아 그 내용에 따라 전체 처리를 진행하고 있다.

내용은 쉽게 이해가 갈거라고 생각한다.

 

델리게이트 같은 경우는 여러함수들이 파라미터에서 델리게이트를 받는 경우가 많기 때문에 사용할줄 알고 의미를 알고 있어야 한다.

 

그림5

 

다른예제를 살펴보자.

델리게이트는 함수를 대리호출해주는 것이라고 했는데 이 대리호출해줄때 여러개의 함수를 동시에 호출 해주도록 만들수도 있다.

이를 델리게이트 체인이라고 한다.

위 예제에서 보면 델리게이트 testd 를 만들고 해당형식을 가지는 델리게이트 변수 _d 를 정의했다.

그리고 버튼 클릭시 tempfunc1 이 호출되도록 했는데 바로 밑에 보면 _d += new testd(tempfunc2); 이런구문이 있다.

최초 _d 가 실행될때 tempfunc1 이 호출된뒤에 tempfunc2 도 호출되도록 만든다는 의미이다.

결국 _d 는 tempfunc1 과 tempfunc2 를 동시에 호출하게 된다.

그리고  아래부분에 보면 _d("aaa") 로 델리게이트를 실행하는 대신에 _d.Invoke("aaa"); 라고 해놨는데 둘다 같은 의미이다.

델리게이트를 실행할때 invoke 를 사용한다고 알아두면 되겠다. 실행시 생략도 가능해서 _d("aaa") 라고 호출할수도 있는것이다.

 

<부분1>

_d -= new testd(tempfunc2);
_d.Invoke("aaa");

 

그림5에서 <부분1> 소스를 없애고 위에서 설명한것만 실행하면 팝업창이 두개 뜨게 된다.

tempfunc1 과 tempfunc2 를 대신 실행한것이다.

그리고 <부분1> 소스를 다시 넣고 실행해보면 팝업창이 하나만 실행되게 된다.

-= 를 이용해 이미 추가된 tempfunc2 을 호출하는 로직을 삭제한것이다.

 

그리고 이 += 과 -= 대신 아래 주석으로 달아놓은 Delegate.Combine 과 Delegate.Remove 를 사용할수도 있다.

해당부분은 직접 연습해보도록 하자.

 

 

***숙제 : 버튼을 누르면 1~100 까지의 숫자중 2의 배수 3의배수 5의 배수중 선택된 항목의 합계를 구하는 프로그램을 만들어보자.(델리게이트 사용)

 

'[ Program ] > c#스터디' 카테고리의 다른 글

54. 람다식  (0) 2022.02.17
53. 무명메서드  (0) 2022.02.08
51. 쓰레드1(Thread)  (0) 2022.02.04
50. 전처리기 / 편의사항  (0) 2021.10.29
49. 디버깅  (0) 2021.10.09

댓글