2009-05-02 3 views
1

Ich begann mit einer Frage, und beim Eintippen der Frage, fand die Antwort, aber anstatt zu löschen, dachte ich, es könnte hilfreich sein, A) eine Bestätigung zu bekommen, und B) anderen zu helfen.Wie kann ein EventHandler den Operator = nur in der Klasse definieren?

Wenn ich ein Ereignis habe und mehrere Orte in der Anwendung Listener hinzufügen, was ist der beste Weg, um alle Listener auf einmal zu entfernen? Zum Beispiel kann ich ...

myPage.OnPageOpened += OpenPage; 

und später in meinem Code ...

myPage.OnPageOpened -= OpenPage; 

Aber was, wenn ich unbekannte 3rd-Party-Abonnenten haben und ich möchte eine magische Reset-Taste drücken, die löscht alles und fängt bei Null an?

Sie können die Operatoren + = und - = an beliebiger Stelle gegen den EventHandler verwenden, da die Operatorüberladungen öffentlich sind. Der = überladene Operator ist privat und kann nur in der definierenden Klasse aufgerufen werden.

Also in der definierenden Klasse kann ich dies verwenden, um meine EventHandler zu löschen.

OnPageOpened = null; 

Und diese Funktionalität zu belichten, könnte ich ...

public void ClearPageOpenedEvents() { 
    OnPageOpened = null; 
} 

Ist das richtig?

+0

Hätte ich Reflektor installiert/geöffnet, wäre dies viel schneller/einfacher zu entdecken gewesen. – ScottCate

Antwort

1

Ja, Sie haben Recht. Der Grund dafür ist, dass der Compiler ein privatedelegate Objekt unter der Decke, wie dies schafft:

private EventHandler pageOpened; 

public EventHandler PageOpened 
{ 
    add { pageOpened += value; } 
    remove { pageOpened -= value; } 
} 

Innerhalb Ihrer Klasse, haben Sie einen Verweis auf die privaten delegate Instanz, also, warum Sie die Zuordnung tun. Sie möchten auf jeden Fall eine Methode zum Löschen der Ziele bereitstellen, wenn diese Funktionalität benötigt wird. Sie möchten nicht die delegate selbst aussetzen.

1

Das ist der Weg, aber wie weiß etwas außerhalb der Klasse, dass die Klasse alle Event-Listener fallen lassen sollte? Was passiert, wenn jemand, der Ihren Code erweitert/verwendet, dieses Ereignis ständig erwartet?

+0

Es ist während eines Reset, wo das Spiel neu beginnt. Ich stimme zu, dass das öffentliche ClearPageOpenedEvents() keine normale Situation ist und mit Vorsicht verwendet werden sollte. – ScottCate

+0

Und sollte wahrscheinlich (zumindest in meinem Fall) intern statt öffentlich sein. – ScottCate

+0

Vielleicht könnten Sie Ihre Objekte entsorgen und neue erstellen. Das würde auch sicherstellen, dass Sie von einem sauberen Zustand ausgehen. Die Bereinigung hat auch den Vorteil, dass Sie keinen Event-Handler verpassen, der gelöscht werden muss, wenn Sie Ihre Klasse erweitern. – JJO

0

Sie können den Zuweisungsoperator für ein Ereignis verwenden, da das Hinzufügen und Entfernen von Ereignissen so funktioniert. Die Verwendung von Reflector beleuchtet viel Licht darüber, wie Ereignisse in C# ausgeführt werden.

die einfache Klasse von

public class MyClass 
{ 
    public event EventHandler MyEvent; 
} 

Der folgende Code Gegeben bei

zusammengestellt produziert wird
public class MyClass 
{ 
    private EventHandler MyEvent; 

    public event EventHandler MyEvent; 
} 

Also, wenn Sie MyEvent verweisen Sie auf den privaten Delegate-Variablen MyEvent beziehen. Die Operatoren += und -= sind "speziell" (weil sie keine Operatoren sind) und werden in den Aufruf der Methoden add und remove geändert, die für das Ereignis erstellt wurden (die den Zuweisungsoperator selbst verwenden).

[MethodImpl(MethodImplOptions.Synchronized)] 
public void add_MyEvent(EventHandler value) 
{ 
    this.MyEvent = (EventHandler) Delegate.Combine(this.MyEvent, value); 
} 

[MethodImpl(MethodImplOptions.Synchronized)] 
public void remove_MyEvent(EventHandler value) 
{ 
    this.MyEvent = (EventHandler) Delegate.Remove(this.MyEvent, value); 
} 
Verwandte Themen