2013-03-03 8 views
6

Wiem, że wydarzenia są zawsze związane z Delegatami. Ale brakuje mi jakiegoś podstawowego wykorzystania wydarzeń i próbuję to zrozumieć.Po co używać wydarzeń, co mogę zrobić z Delegatami?

stworzyłem prosty program wydarzeń, jak poniżej, i to działa perfekcyjnie.

namespace CompleteRef3._0 
{ 
delegate void someEventDelegate(); 

class EventTester 
{ 
    public event someEventDelegate someEvent; 

    public void doEvent() 
    { 
     if (someEvent != null) someEvent(); 
    } 

} 

class Program 
{ 
    static void EventHandler1() 
    { 
     Console.WriteLine("Event handler 1 called.."); 
    } 

    static void EventHandler2() 
    { 
     Console.WriteLine("Event handler 2 called.."); 
    } 
    static void EventHandler3() 
    { 
     Console.WriteLine("Event handler 3 called.."); 
    } 


    static void Main(string[] args) 
    { 
     EventTester evt = new EventTester(); 
     evt.someEvent += EventHandler1; 
     evt.someEvent += EventHandler2; 
     evt.someEvent += EventHandler3; 
     evt.doEvent(); 
     Console.ReadKey(); 

    } 
} 
} 

Zastąpiłem deklarację zdarzenia delegatami. To ja zastąpiłem linię publiczną publiczne wydarzenie someEventDelegate someEvent; z someEventDelegate someEvent; w powyższym programie i nadal otrzymuję ten sam wynik. Teraz byłem zdezorientowany, dlaczego potrzebujemy korzystać z Wydarzenia, jeśli może to być osiągnięte tylko przez Delegatów. Jakie jest prawdziwe wykorzystanie wydarzeń?

Zmodyfikowany Program bez zdarzeń jest jak poniżej -

namespace CompleteRef3._0 
{ 
delegate void someEventDelegate(); 

class EventTester 
{ 
    someEventDelegate someEvent; 

    public void doEvent() 
    { 
     if (someEvent != null) someEvent(); 
    } 

} 

class Program 
{ 
    static void EventHandler1() 
    { 
     Console.WriteLine("Event handler 1 called.."); 
    } 

    static void EventHandler2() 
    { 
     Console.WriteLine("Event handler 2 called.."); 
    } 
    static void EventHandler3() 
    { 
     Console.WriteLine("Event handler 3 called.."); 
    } 


    static void Main(string[] args) 
    { 
     EventTester evt = new EventTester(); 
     evt.someEvent += EventHandler1; 
     evt.someEvent += EventHandler2; 
     evt.someEvent += EventHandler3; 
     evt.doEvent(); 
     Console.ReadKey(); 

    } 
} 
} 
+0

Krótko mówiąc, udostępnianie przerw na delegacje publiczne ** enkapsulacja **. – Timeless

Odpowiedz

4

Oczywiście, można użyć delegatów ponieważ za kulisami zdarzenie jest konstrukt, który owija delegata.

Ale uzasadnienie użycia zdarzeń zamiast delegatów jest takie samo, jak w przypadku używania właściwości zamiast pól - enkapsulacja danych. Zła praktyka polega na bezpośrednim ujawnianiu pól (czymkolwiek one są - prymitywnymi polami lub delegatami).

Nawiasem mówiąc, przegapiłeś public słowa kluczowego przed swoim polu delegata, aby umożliwić w drugim fragmencie.

Kolejne "przy okazji" z drugim fragmentem: dla delegatów powinieneś użyć Delegate.Combine zamiast "+ =".

+0

oh ya .. mój błąd przeoczyłem słowo kluczowe 'publiczne' .. dzięki za złapanie go dla mnie. Zmienię to. Dobra znajomość dla mnie do używania 'Delegate.Combine'. Nie wiedziałem o tym wcześniej! ... Twoja odpowiedź jest dobra, dokładnie to, co myślałem - *** hermetyzacja danych ***. –

+3

Dobra odpowiedź, z wyjątkiem ostatniej linii. ** Dlaczego nie powinniśmy używać '+' i '+ =' i tak dalej z delegatami? ** Zostały wprowadzone do języka, aby wszystko było piękne. Nadal ważne jest zrozumienie różnicy między '+ =' ze zdarzeniami (składnia do wywoływania accessora 'add') i' + = 'ze zmiennymi (tutaj' x + = y' jest podobne do 'x = x + y' gdzie '+' może być kombinacją delegowania, konkatenacją łańcuchów, dodatkiem arytmetycznym jakiegoś typu lub innymi przeciążeniami). Jednym z problemów z 'Delegate.Combine' jest to, że typy nie są sprawdzane przez cały czas kompilacji. Z '+' sprawdzane są typy kompilacji. –

7

Głównym celem wydarzenia jest zapobieganie zakłócaniu abonentów ze sobą. Jeśli nie użyć zdarzenia można:

zastąpienia innych abonentów, zmieniając delegata (zamiast używać operatora + =), Wyczyść wszystkich abonentów (poprzez ustawienie delegata do null), rozsyłanych do innych abonentów, powołując się na delegat.

Źródło: C# w pigułce

+3

+1. Przydzielenie 'someEvent = new someEventDelegate (EventHandler2)' jest problemem, który masz przy bezpośrednim użyciu delegów. Kolejny link [Learning C# 3.0: opanuj podstawy C# 3.0 - Delegaci i zdarzenia] (http://msdn.microsoft.com/en-us/library/orm-9780596521066-01-17.aspx) - ten rozdział jest avialble na MSDN i idzie do szczegółów na ten temat. –

+0

dzięki za twój referencję .. –

5

Wyobraź masz 3 abonentów, którzy są zainteresowani w someEvent.Wnieśli do nawet tak:

Client 1

EventTester evt = new EventTester(); 
evt.someEvent += Client1Handler1; 
evt.someEvent += Cleint1Handler2; 

Client 2

EventTester evt = new EventTester(); 
evt.someEvent += Client2Handler1; 
evt.someEvent += Client2Handler2; 

Client 3

EventTester evt = new EventTester(); 
evt.someEvent += Client2Handler1; 
evt.someEvent += Client2Handler2; 

teraz wyobrazić innego klienta czyni to:

EventTester = null; 

Client 1, 2 i 3 nie będzie dostawać żadnych wydarzeń, bo trzeba tę linię kodu:

if (someEvent != null) someEvent(); 

Nie ma nic złego w powyższej linii kodu, ale istnieje problem z użyciem delegatów .

Innym problemem jak Alexei wskazał to:

someEvent = new someEventDelegate(EventHandler2) 

Jeśli masz event i jeden z klientów próbowali wyżej, nie będzie dozwolone, a otrzymasz błąd kompilacji, tak:

enter image description here

+0

Dziękuję. Bardzo dobrze wytłumaczyłeś użycie wydarzenia. :) –