Share via


대리자 및 이벤트를 구별

이전

.NET Core 플랫폼을 처음 사용하는 개발자는 delegates 기반 디자인과 events 기반 디자인 중에서 결정할 때 종종 어려움을 겪습니다. 두 언어 기능이 유사하므로 대리자 또는 이벤트를 선택하는 것이 어렵습니다. 이벤트는 대리자에 대한 언어 지원을 사용하여 작성되기도 합니다.

둘 다 런타임 바인딩 시나리오를 제공합니다. 즉, 런타임에만 알려지는 메서드를 호출하여 구성 요소가 통신하는 시나리오를 지원합니다. 모두 단일 및 다중 구독자 메서드를 지원하는데, 이를 단일 캐스트 및 멀티캐스트 지원이라고 할 수 있습니다. 둘 다 처리기 추가 및 제거에 대해 유사한 구문을 지원합니다. 마지막으로 이벤트를 발생시키고 대리자를 호출하는 작업에서 정확히 동일한 메서드 호출 구문을 사용합니다. 또한 ?. 연산자와 함께 사용하도록 동일한 Invoke() 메서드 구문을 지원합니다.

이러한 모든 유사성으로 인해 언제 어떤 언어 기능을 사용할지를 결정하기가 어려울 수 있습니다.

이벤트 수신은 선택 사항임

사용할 언어 기능을 결정할 때 가장 중요하게 고려할 사항은 연결된 구독자가 있어야 하는지 여부입니다. 코드에서 구독자가 제공하는 코드를 호출해야 하는 경우에는 콜백을 구현해야 할 때 대리자 기반 디자인을 사용해야 합니다. 코드에서 구독자를 호출하지 않고 모든 작업을 완료할 수 있는 경우에는 이벤트 기반 디자인을 사용해야 합니다.

이 섹션 중 작성된 예제를 살펴보겠습니다. List.Sort()를 사용하여 작성한 코드에서 요소를 제대로 정렬하려면 비교자 함수가 제공되어야 합니다. 반환할 요소를 결정하려면 대리자와 함께 LINQ 쿼리를 제공해야 합니다. 둘 다 대리자로 작성된 디자인을 사용했습니다.

Progress 이벤트를 살펴보겠습니다. 이 이벤트는 작업의 진행률을 보고합니다. 수신기가 있는지 여부에 관계없이 작업이 계속 진행됩니다. FileSearcher는 또 다른 예제입니다. 연결된 이벤트 구독자가 없는 경우에도 검색된 모든 파일을 계속 검색하고 찾습니다. UX 컨트롤은 이벤트를 수신하는 구독자가 없는 경우에도 여전히 올바르게 작동합니다. 둘 다 이벤트 기반 디자인을 사용합니다.

반환 값에 대리자 필요

또 다른 고려 사항은 대리자 메서드에 필요한 메서드 프로토타입입니다. 지금까지 살펴본 대로 이벤트에 사용된 대리자는 모두 void 반환 형식을 갖습니다. 또한 이벤트 인수 개체의 속성을 수정하여 이벤트 소스에 다시 정보를 전달하는 이벤트 처리기를 만드는 관용구가 있음을 확인했습니다. 이러한 관용구도 작업을 수행하기는 하지만 메서드에서 값을 반환하는 것만큼 자연스럽지 않습니다.

이러한 두 추론은 종종 둘 다 제공될 수 있습니다. 대리자 메서드가 값을 반환하는 경우 어떤 방식으로든 알고리즘에 영향을 줄 가능성이 있습니다.

이벤트에 프라이빗 호출이 있음

이벤트가 포함된 클래스가 아닌 다른 클래스는 이벤트 수신기를 추가하고 제거할 수만 있습니다. 이벤트가 포함된 클래스만 이벤트를 호출할 수 있습니다. 이벤트는 일반적으로 공용 클래스 멤버입니다. 반면 대리자는 종종 매개 변수로 전달되고 프라이빗 클래스 멤버로 저장됩니다(저장되는 경우).

종종 이벤트 수신기의 수명이 길어짐

이 이벤트 수신기는 수명이 길수록 근거가 약간 약해집니다. 그러나 이벤트 소스가 오랜 시간 동안 이벤트를 발생시킬 경우에는 이벤트 기반 디자인이 더 자연스러울 수 있습니다. 많은 시스템에서 UX 컨트롤의 이벤트 기반 디자인 예제를 확인할 수 있습니다. 이벤트를 구독하면 이벤트 소스가 프로그램의 수명 주기 전체에 걸쳐 이벤트를 발생시킬 수 있습니다. 이벤트가 더 이상 필요하지 않은 경우 이벤트 구독을 취소할 수 있습니다.

대리자가 메서드의 인수로 사용되고 해당 메서드가 반환된 후에는 대리자가 사용되지 않는 많은 대리자 기반 디자인과 비교해 보세요.

신중하게 평가

위의 고려 사항은 엄격한 규칙이 아닙니다. 대신 특정 용도에 가장 적합한 선택 항목을 결정하는 데 도움이 되는 지침을 나타냅니다. 유사하기 때문에 둘 다를 프로토타입화할 수도 있고 작업에 더 자연스러운 항목을 고려할 수 있습니다. 둘 다 런타임에 바인딩 시나리오도 처리합니다. 최상의 디자인을 전달하는 기능을 사용하세요.