(to wszystko z perspektywy C#).
Mam article about the differences between events and delegates. Obejmuje to wszystko, o czym wspomniano poniżej, o wiele bardziej szczegółowo.
Zasadniczo lubię myśleć o wydarzeniu jako o własności - to para metod, to wszystko. Zamiast get/set, zdarzenie dodało/usunęło - co oznacza "dodaj ten moduł obsługi zdarzeń" i "usuń ten moduł obsługi zdarzeń". Najważniejsze jest to wydarzenie.
C# ma również pola jak wydarzenia będące skrót:
public event EventHandler Foo;
deklaruje zarówno pole i zdarzenie, o prawie trywialny dodaj/usuń realizację. W klasie odwołanie do Foo
odnosi się do pola. Poza zajęciami, odwołanie do Foo
odnosi się do zdarzenia.
Podstawową ideą jest to, że zdarzenie pozwala innemu kodowi subskrybować i wypisać się z niego, przekazując uczestnika (zdarzenie handler). Zazwyczaj subskrypcja jest implementowana przez utworzenie nowego uczestnika multiemisji zawierającego listę poprzedniej listy programów obsługi zdarzeń i nowej.Więc jeśli przechowywania obsługi zdarzeń w polu o nazwie myEventHandlers
, realizacja subskrypcja może być:
myEventHandlers += value;
Podobnie wypisania zwykle polega na utworzeniu nowego delegata multicast bez określony Handler:
myEventHandlers -= value;
Następnie, gdy chcesz podnieść/wystrzelić zdarzenie, po prostu zadzwoń do tego delegata multiemisji - zwykle z kontrolą nieważności, aby uniknąć zgłaszania wyjątku, jeśli nikt nie subskrybował:
EventHandler handler = myEventHandlers;
if (handler != null)
{
// You could pass in a different "sender" and "args" of course
handler(this, EventArgs.Empty);
}
Korzystając z wydarzeń, subskrybenci nie wiedzą o sobie nawzajem i nie mogą samodzielnie podnieść zdarzenia (zwykle). Innymi słowy, jest to wzór enkapsulacji, który otrzymał status zarówno w języku, jak i na platformie.
Nie, wydarzenia * nie są * delegatami. Zdarzenia to zasadniczo metody dodawania/usuwania. Mówienie, że wydarzenia są delegatami, jest jak powiedzenie, że właściwości są polami. –
Właściwości IMHO MUSZĄ zachowywać się jak pola, dokładnie tak jak wydarzenia będą zachowywać się jak delegaci multicast. W przeciwnym wypadku jest to mylące dla użytkownika klasy, ponieważ dostęp do właściwości i pola wygląda podobnie w źródle, jak wysyłanie zdarzeń i wysyłanie delegatów. Nie oznacza to, że właściwość lub zdarzenie musi korzystać z domyślnej implementacji (pole zaplecza, delegowanie multiemisji zastępczej). Oznacza to po prostu "właściwość/pole: Uzyskaj/ustaw wartość bez efektów ubocznych" i "wydarzenie/deleguj: uruchom wywołanie zwrotne". Dzięki właściwościom/zdarzeniom, język daje wiele sznurów, których możesz użyć rozsądnie lub powiesić się. – froh42