본문 바로가기
개인 스터디

Delegate 에서 Event

by 태운콩즙 2024. 10. 7.
728x90
반응형

모든 이벤트는 특수한 형태의 delegate이다 C#의 delegate 기능은 경우에 따라 잘못 사용될 소지가 있다. 예를 들어 우리가 Button 컨트롤을 개발해 판매한다고 하면 이 컨드롤 은 delegate 필드를 가지고 있고 버튼 클릭 시 InvokeList에 있는 모든 메서드 들을 차례로 실행하도록 하였다 그런데 Button 컨트롤을 구입한 개발자가 한 컴포넌트 에서 추가 연산(+=)을 사용 하지 않고 실수로 할당 연산자(=)를 사용하였다고 가정하자 이 할당 연산은 기존에 가입된 모든 메서드 리스트를 지워버리고 마지막에 할당한 메서드 한 개만 InvokeList에 넣게 할 것이다 즉, 누그든 할당 연산자를 한번 사용하면 기존에 가입 받은 모든 메서드 호출 요구를 삭제하는 문제가 발생한다

이러한 문제점과 더불어 또 다른 중요한 문제점은 delegate는 해당 클래스 내부에서 뿐만 아니라 외부에서도 누구라도 메서드를 호출하듯 해당 delegate를 호출 할 수 있다는 점이다 아래 예제는 할당 연산자를 사용해서 기존 delegate를 덮어쓰는 예와 delegate 를 외부에서 호출하는 예를 보여준다

예제

        static void Main(string[] args)
        {
            area = new MyArea();

            area.MyClick += Area_Click;
            area.MyClick += AfterClick;

            area.Show();

            // 덮어쓰기: MyClick은 Area_Click메서드만 갖는다
            area.MyClick = Area_Click;

            // C# delegate는 클래스 외부에서 호출할 수 있다.
            // C# event는 불가
            area.MyClick(null);
        }

C#Event의 특성

위와 같은 delegate 의 문제점들을 극복하기 위해서 특별한 형태의 delegate 로서의 C# event를 사용할 수 있다 C# event는 할당연산자(=) 를 사용할수 없으며 오직 이벤트 핸들러 추가 (+=연산자, Subscribe)혹은 기존 이벤트 핸들러 삭제 (-= 연산자, Unsubscribe) 만을 할수 있다 또한 delegate 와는 달리 해당 클래스 외부에서는 직접 이벤트를 호출 할수 없다

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp4
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.MouseClick += delegate { MyAreaClick(); };
        }
        public delegate void ClickEvent(object sender);

        // event 필드
        public event ClickEvent MyClick;
        // 예제를 단순화 하기위해
        // MyArea가 클릭되면 아래 함수가 호출된다고 가정
        void MyAreaClicked()
        {
            if (MyClick != null) 
            {
                MyClick(this);
            }
        }
    }
    class Program
    {
        static MyArea area;

        static void Main(string[] args)
        {
            area = new MyArea();

            // 이벤트 가입
            area.MyClick += Area_Click;
            area.MyClick += AfterClick;

            // 이벤트 탈퇴
            area.MyClick -= Area_Click;

            // Error : 이벤트 직접 호출 불가
            // area.MyClick(this);

            area.ShowDialog();
        }
        static void Area_Click(object sender)
        {
            area.Text += "MyArea 클릭!";
        }
        static void AfterClick(object sender)
        {
            area.Text += "AfterClick 클릭!";
        }
    }
}

728x90
반응형

'개인 스터디' 카테고리의 다른 글

Win Sock 과 .NET 클래스  (1) 2024.10.11
시리얼 통신  (0) 2024.10.10
Spring MVC 웹서버 구동 방식  (0) 2024.02.05
스프링 프레임워크의 방식  (2) 2024.02.04
프레임 워크  (0) 2024.02.02