2013-03-03 1 views
6

Ich weiß, Ereignisse sind immer Delegaten zugeordnet. Aber ich vermisse etwas Kernnutzung von Events und versuche das zu verstehen.Warum Ereignisse für das, was ich mit Delegaten tun kann, verwenden?

Ich erstellte ein einfaches Event-Programm, wie unten, und es funktioniert einwandfrei.

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(); 

    } 
} 
} 

Ich ersetzte die Event-Deklaration durch Delegaten. Das ist ich ersetzte die Linie öffentliches Ereignis someEventDelegate someEvent; mit someEventDelegate someEvent; auf das obige Programm, und ich bekomme immer noch das gleiche Ergebnis. Jetzt war ich verwirrt, warum wir Ereignisse verwenden müssen, wenn es nur von Delegierten erreicht werden kann. Wie werden Events wirklich genutzt?

Das modifizierte Programm ohne Ereignisse ist als unten -

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

Kurz gesagt, öffentliche Delegierten bricht ** Einkapselung **. – Timeless

Antwort

4

Sicher, können Sie Delegaten verwenden, weil hinter den Kulissen ein Ereignis ist ein Konstrukt, das einen Delegaten einwickelt.

Aber die Logik der Verwendung von Ereignissen anstelle von Delegaten ist die gleiche wie für die Verwendung von Eigenschaften anstelle von Feldern - Datenkapselung. Es ist eine schlechte Praxis, Felder (was auch immer sie sind - primitive Felder oder Delegaten) direkt verfügbar zu machen.

Übrigens, Sie vermissten ein Schlüsselwort public vor Ihrem Delegiertenfeld, um es im zweiten Snippet zu ermöglichen.

Ein weiteres "nebenbei" mit dem zweiten Ausschnitt: Für Delegierte sollten Sie Delegate.Combine anstelle von "+ =" verwenden.

+0

oh ya .. mein Fehler Ich vermisste das 'public' Schlüsselwort .. danke für den Fang für mich. Ich werde es bearbeiten .. Gutes Wissen für mich, 'Delegate.Combine' zu ​​verwenden. Ich wusste es vorher nicht! ... Ihre Antwort ist gut, genau, was ich dachte - *** Datenkapselung ***. –

+3

Gute Antwort mit Ausnahme der letzten Zeile. ** Warum sollten wir nicht '+' und '+ =' usw. mit Delegierten verwenden? ** Sie wurden in die Sprache eingefügt, um die Dinge hübsch zu machen. Es ist immer noch wichtig, den Unterschied zwischen '+ =' mit Ereignissen (eine Syntax zum Aufruf des 'add'-Ereignis-Accessors) und' + = 'mit Variablen zu verstehen (hier ist x + = y' wie 'x = x + y 'wo' + 'Delegiertenkombination, String-Verkettung, arithmetische Addition eines Typs oder andere Überladungen sein kann. Ein Problem mit 'Delegate.Combine' ist, dass Typen nicht zur Kompilierzeit überprüft werden. Mit '+' werden die Kompilierzeittypen überprüft. –

7

Der Hauptzweck der Ereignisse ist Abonnenten stören miteinander zu verhindern. Wenn Sie Ereignisse nicht verwenden, können Sie:

andere Teilnehmer ersetzen durch Delegierte Neuzuweisung (statt mit dem Operator + =), Löschen Sie alle Abonnenten (indem Delegierten auf null), Übertragung an andere Teilnehmer durch die Berufung delegieren.

Quelle: C# in a Nutshell

+3

+1. Zuweisung 'someEvent = new someEventDelegate (EventHandler2)' ist das Problem, das Sie bei der direkten Verwendung von Delegierten haben. Ein weiterer Link [Learning C# 3.0: Meistern Sie die Grundlagen von C# 3.0 - Delegaten und Veranstaltungen] (http://msdn.microsoft.com/en-us/library/orm-9780596521066-01-17.aspx) - dieses besondere Kapitel ist Avial auf MSDN und geht auf Details zu diesem Thema. –

+0

danke für Ihre Referenz .. –

5

Stellen Sie sich vor Sie haben 3 Abonnenten, die an Ihrem someEvent interessiert sind.Sie haben sich an die selbst wie folgt gezeichnet:

-Client 1

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

Kunde 2

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

-Client 3

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

nun einen anderen Client vorstellen, tut dies:

EventTester = null; 

Client 1, 2 und 3 werden keine Ereignisse bekommen, weil Sie diese Codezeile haben:

if (someEvent != null) someEvent(); 

Es ist nichts falsch mit der obigen Codezeile, aber es ist das Problem mit den Delegierten mit .

Das andere Problem, wie Alexei wies darauf hin, ist:

someEvent = new someEventDelegate(EventHandler2) 

Wenn Sie ein event und einer der Kunden die oben versucht, sie werden nicht erlaubt und einen Compiler-Fehler erhalten werden, wie folgt aus:

enter image description here

+0

Danke. Sie haben die Verwendung von Event sehr gut erklärt. :) –