Wprowadzenie do zdarzeń
Zdarzenia są, takie jak delegaty, mechanizm późnego powiązania . W rzeczywistości zdarzenia są oparte na obsłudze języka dla delegatów.
Zdarzenia to sposób emisji obiektu (do wszystkich zainteresowanych składników w systemie), który wystąpił. Każdy inny składnik może subskrybować zdarzenie i otrzymywać powiadomienia o wystąpieniu zdarzenia.
Prawdopodobnie używałeś wydarzeń w niektórych programach. Wiele systemów graficznych ma model zdarzeń do raportowania interakcji użytkownika. Te zdarzenia zgłaszałyby ruch myszy, naciśnięcia przycisku i podobne interakcje. Jest to jeden z najczęstszych, ale z pewnością nie jedyny scenariusz, w którym są używane zdarzenia.
Można zdefiniować zdarzenia, które powinny być zgłaszane dla klas. Jedną z ważnych kwestii podczas pracy ze zdarzeniami jest to, że nie może istnieć żaden obiekt zarejestrowany dla określonego zdarzenia. Należy napisać kod, aby nie zgłaszał zdarzeń, gdy nie skonfigurowano żadnych odbiorników.
Subskrybowanie zdarzenia powoduje również utworzenie sprzężenia między dwoma obiektami (źródłem zdarzeń i ujściem zdarzenia). Należy upewnić się, że ujście zdarzeń anuluje subskrypcję źródła zdarzeń, gdy nie jest już zainteresowany zdarzeniami.
Cele projektowania pod kątem obsługi zdarzeń
Projekt języka dla zdarzeń jest przeznaczony dla następujących celów:
Umożliwia bardzo minimalne sprzęganie między źródłem zdarzeń a ujściem zdarzeń. Te dwa składniki mogą nie być napisane przez tę samą organizację, a nawet mogą być aktualizowane zgodnie z zupełnie różnymi harmonogramami.
Subskrybowanie zdarzenia powinno być bardzo proste i anulowanie subskrypcji tego samego zdarzenia.
Źródła zdarzeń powinny obsługiwać wielu subskrybentów zdarzeń. Powinna również obsługiwać brak dołączonych subskrybentów zdarzeń.
Widać, że cele dla zdarzeń są bardzo podobne do celów delegatów. Dlatego obsługa języka zdarzeń jest oparta na obsłudze języka delegowanego.
Obsługa języka zdarzeń
Składnia definiowania zdarzeń i subskrybowania lub anulowania subskrypcji zdarzeń jest rozszerzeniem składni dla delegatów.
Aby zdefiniować zdarzenie, użyj słowa kluczowego event
:
public event EventHandler<FileListArgs> Progress;
Typ zdarzenia (EventHandler<FileListArgs>
w tym przykładzie) musi być typem delegata. Istnieje wiele konwencji, które należy przestrzegać podczas deklarowania zdarzenia. Zazwyczaj typ delegata zdarzenia ma zwracaną wartość void.
Deklaracje zdarzeń powinny być czasownikiem lub frazą czasownika.
Użyj napiętej przeszłości, gdy zdarzenie zgłasza coś, co się stało. Użyj czasownika czasownika bieżącego (na przykład ), aby zgłosić coś, Closing
co ma się zdarzyć. Często użycie napiętej liczby obecnych wskazuje, że klasa obsługuje pewnego rodzaju zachowanie dostosowywania. Jednym z najbardziej typowych scenariuszy jest obsługa anulowania. Na przykład Closing
zdarzenie może zawierać argument, który wskazuje, czy operacja zamknięcia powinna być kontynuowana, czy nie. Inne scenariusze mogą umożliwić obiektom wywołującym modyfikowanie zachowania, aktualizując właściwości argumentów zdarzeń. Możesz zgłosić zdarzenie, aby wskazać proponowaną następną akcję, którą podejmie algorytm. Procedura obsługi zdarzeń może nadać inną akcję, modyfikując właściwości argumentu zdarzenia.
Jeśli chcesz zgłosić zdarzenie, wywołaj programy obsługi zdarzeń przy użyciu składni wywołania delegata:
Progress?.Invoke(this, new FileListArgs(file));
Jak opisano w sekcji dotyczącej delegatów, ?. operator ułatwia zapewnienie, że nie próbujesz zgłosić zdarzenia, gdy nie ma subskrybentów tego zdarzenia.
Zasubskrybujesz zdarzenie przy użyciu +=
operatora :
EventHandler<FileListArgs> onProgress = (sender, eventArgs) =>
Console.WriteLine(eventArgs.FoundFile);
fileLister.Progress += onProgress;
Metoda obsługi zwykle ma prefiks "Włączone", po którym następuje nazwa zdarzenia, jak pokazano powyżej.
Anulujesz subskrypcję przy użyciu -=
operatora:
fileLister.Progress -= onProgress;
Ważne jest zadeklarowanie zmiennej lokalnej dla wyrażenia reprezentującego procedurę obsługi zdarzeń. Dzięki temu anulowanie subskrypcji spowoduje usunięcie programu obsługi. Jeśli zamiast tego użyto treści wyrażenia lambda, próbujesz usunąć procedurę obsługi, która nigdy nie została dołączona, co nic nie robi.
W następnym artykule dowiesz się więcej o typowych wzorcach zdarzeń i różnych odmianach w tym przykładzie.