Ich verstehe nicht, warum wir das Schlüsselwort "event" beim Definieren von Ereignissen benötigen, wenn wir dasselbe tun können, ohne das Schlüsselwort "event" zu verwenden, nur indem wir die Delegaten verwenden.
z.B
public delegate void CustomEventHandler(int a, string b);
public event CustomEventHandler customEvent;
customEvent += new CustomEventHandler(customEventHandler);
customEvent(1,"a"); // Raising the event
Wenn ich hier das Schlüsselwort "event" aus der zweiten Zeile entferne, kann ich das Ereignis auch durch Aufrufen des Delegaten auslösen. Kann mir bitte jemand sagen, warum dieses Ereignis-Keyword benötigt wird?
Antworten:
Feldähnliche Ereignisse und öffentliche Felder von Delegatentypen sehen ähnlich aus, sind jedoch tatsächlich sehr unterschiedlich.
Ein Ereignis ist im Grunde wie eine Eigenschaft - es ist ein Paar von Add / Remove-Methoden (anstelle des get / set einer Eigenschaft). Wenn Sie ein feldähnliches Ereignis deklarieren (dh ein Ereignis, bei dem Sie die Add / Remove-Bits nicht selbst angeben), wird ein öffentliches Ereignis und ein privates Hintergrundfeld erstellt. Auf diese Weise können Sie das Ereignis privat auslösen, jedoch ein öffentliches Abonnement zulassen. Mit einem öffentlichen Delegiertenfeld kann jeder die Ereignishandler anderer Personen entfernen, das Ereignis selbst auslösen usw. - dies ist eine Kapselungskatastrophe.
Weitere Informationen zu Veranstaltungen (und Delegierten) finden Sie in meinem Artikel zu diesem Thema . (Irgendwann muss ich dies für C # 4 aktualisieren, wodurch sich feldähnliche Ereignisse nur geringfügig ändern. Der Kern ist jedoch immer noch korrekt.)
quelle
Das Ereignis-Schlüsselwort macht drei verschiedene Dinge:
=
und()
(Zuweisung und Aufruf) in privat, sodass nur die enthaltende Klasse das Ereignis aufrufen oder alle darin enthaltenen Methoden überschreiben kann. Die Operatoren-=
und+=
können weiterhin für ein Ereignis von außerhalb der Klasse aufgerufen werden, die es definiert (sie erhalten den Zugriffsmodifikator, den Sie neben dem Ereignis geschrieben haben).-=
und Weise überschreiben und+=
sich bei Ereignissen verhalten.quelle
Die anderen Antworten sind in Ordnung; Ich möchte nur noch etwas hinzufügen, über das ich nachdenken kann.
Ihre Frage lautet: "Warum brauchen wir Ereignisse, wenn wir Felder vom Typ Delegat haben?" Ich würde diese Frage erweitern: Warum benötigen Sie Methoden, Eigenschaften, Ereignisse, Instanzkonstruktoren oder Finalizer, wenn Sie Felder vom Typ Delegat haben? Warum benötigen Sie etwas anderes als Felder, die Werte und Delegaten in einem Typ enthalten? Warum nicht einfach sagen
?
Sie müssen nicht brauchen Methoden, Eigenschaften oder Ereignisse. Wir geben Ihnen diese Informationen, da die Entwurfsmuster für Methoden, Eigenschaften und Ereignisse wichtig und nützlich sind und eine standardisierte, dokumentierte und klare Möglichkeit verdienen, sie in der Sprache zu implementieren.
quelle
Es wird teilweise benötigt, da
event
die Kapselung unterbrochen wird, wenn Sie das Schlüsselwort weglassen . Wenn es sich nur um einen öffentlichen Multicast-Delegaten handelt, kann jeder ihn aufrufen, auf null setzen oder manipulieren. Wenn eine aufgerufene KlasseMailNotifier
existiert und ein Ereignis aufgerufen wurdeMailReceived
, ist es für andere Typen nicht sinnvoll, dieses Ereignis per AufrufmailNotifier.MailReceived()
auszulösen.Auf der anderen Seite können Sie sich nur in feldähnliche Ereignisse des Typs einmischen und diesen aufrufen, der sie definiert hat.
Wenn Sie Ihren Ereignisaufruf privat halten möchten, hindert Sie nichts daran, Folgendes zu tun:
... aber das ist eine ganze Menge Code, nur um (mehr oder weniger) das zu tun, was feldähnliche Ereignisse uns bereits geben.
quelle
Ereignisse haben deutliche Vorteile gegenüber Delegatenfeldern. Ereignisse können in Schnittstellen im Gegensatz zu Feldern definiert werden, wodurch dem Code eine Abstraktion hinzugefügt wird, und noch wichtiger: Ereignisse können nur innerhalb der definierenden Klasse aufgerufen werden. In Ihrem Fall könnte jeder das Ereignis aufrufen und möglicherweise Ihren Code zerstören.
Weitere Informationen finden Sie in diesem Blogbeitrag .
quelle
Delegat ist ein Referenztyp. Es erbt MulticastDelegate . Veranstaltung ist ein Modifikator. Veranstaltungist ein spezieller Modifikator für Delegierte. Es ändert einige Funktionen / Methoden, z. B. die Invoke-Methode. Nach dem Ändern durch ein Modifikatorereignis wird eine Delegateninstanz zu einem neuen Konzept "Ereignis". Event ist also nur ein modifizierter Delegat. Sie können die Referenz nicht direkt ändern oder ein Ereignis außerhalb der Klasse aufrufen, in der das Ereignis definiert wurde. Sie können jedoch die Referenz ändern oder eine normale Delegateninstanz aufrufen. Event bietet zusätzlichen Schutz, sodass Event mehr Sicherheitsfunktionen bietet. Wenn Sie sich außerhalb der Klasse befinden, in der das Ereignis definiert wurde, können Sie zwei Arten von Operationen für das Ereignis ausführen: "+ =" und "- =". Sie können jedoch auf alle öffentlichen Felder, Eigenschaften, Methoden usw. einer normalen Delegateninstanz zugreifen. Hier ist ein Beispiel:
quelle