2016-04-21 6 views
-2

Ich habe eine Situation, in der mehrere Klassen Interesse an einer anderen Klasse registrieren, um den Wert einer bestimmten Eigenschaft zu beobachten. Dies wird durch die Verwendung Delegierten erfolgt wie folgt:C# überprüfen, ob delegate/func einen gültigen Empfänger hat

public delegate void ObservingHandler (object value); 

Dictionary<ObservingHandler, ObservationInfo> _handlers = new Dictionary<ObservationHandler, ObservationInfo>(); 

public void register(ObservingHandler handler) { 

    // Observation info is created here and is just a struct 
    _handlers.Add(handler, info); 
} 

Dies funktioniert gut und ist wirklich nützlich, aber zur Zeit, wenn ein registriertes Objekt freigegeben wird, hat es die entsprechende Klasse zu sagen, dass es nicht mehr will, Benachrichtigungen erhalten. Ansonsten bekomme ich NULL Referenz Ausnahmen.

Derzeit bedeutet dies, dass ich keine Lambda-Ausdrücke verwenden kann, weil der Beobachtungshandler der Schlüssel im Wörterbuch ist (und daher dieselbe Instanz sein muss, wenn es darauf ankommt).

Was ich tun möchte, ist zu überprüfen, dass jede ObservationHandler eine gültige und instanziierte Klasse dahinter hat, bevor es aufgerufen wird. Auf diese Weise wird die Verantwortung von der Hörklasse genommen.

Gibt es einen Weg in Func oder delegate zu überprüfen, Empfänger der Funktion ist am Leben und gut?

EDIT:

Der vollständige Quellcode stammt von meinem Projekt namens SFCore on GitHub.

+2

"Ansonsten bekomme ich Exceptpions" - welche Ausnahmen? Es ist nicht wirklich klar, was Sie meinen - zeigen Sie bitte ein [mcve], das das Problem demonstriert. –

+0

Der 'ObservingHandler' ist eine Referenz auf eine Methode in einer Beobachtungsklasse. Wenn die beobachtende Klasse freigegeben wird, enthält der 'ObservingHandler' eine Referenz auf eine Methode in einer Null-Klasse. Ich glaube, die Ausnahme ist eine Null-Referenz-Ausnahme. Also muss ich jetzt die beobachtende Klasse vor der Veröffentlichung abmelden lassen, aber ich würde gerne in der Lage sein zu sagen, ob der "ObservingHandler" einen instanziierten Beobachter hat, der an ihn angehängt ist. –

+0

Anstatt zu glauben, dass die Ausnahme eine NullReferenceException ist, warum zeigen Sie uns kein Beispiel? Ich würde erwarten, dass die ObservingHandler-Referenz das Ziel automatisch am Leben erhält - es gibt hier keine "Freigabe". Grundsätzlich, bis Sie das Problem in einer prägnanten Form reproduzieren können, wird es sehr schwierig sein, Ihnen zu helfen. –

Antwort

1

Ich würde mit dem .NET-Ereignismodell gehen und die Verantwortung beim Hörer belassen, denn wenn Ihr Test aus irgendeinem Grund fehlschlägt, wird Ihr Empfänger nicht mehr benachrichtigt.

Was ich tun würde, ist, während der Benachrichtigung der Zuhörer, irgendwelche Ausnahmen, die auftreten können.

Wenn eine Ausnahme auftritt, die auf eine nicht mehr existierende Klasse zurückzuführen ist (genauer gesagt, Sie haben uns nicht den genauen Namen der Ausnahme gegeben), würden Sie sie entweder ignorieren (denken Sie, dass es nur ein einziges Mal ist) Fehler) ODER entfernen Sie es aus dem Wörterbuch.

Auch das würde ich tun, es gibt sicherlich andere Methoden, um das zu erreichen.

+0

Danke, das ist eine gute Idee. Gibt es eine Möglichkeit, die Sie vor der Benachrichtigung eines Zuhörers wissen müssen, wenn der Zuhörer tatsächlich existiert? Ich gehe davon aus, dass "Event" das tut, aber ich habe keine Ahnung wie. –

0

Die Observer pattern in C# wird mit Ereignissen erreicht. Verwenden Sie das event Schlüsselwort basierend auf Ihrer Beschreibung.

Sie müssen nicht die Callbacks auf dieser Ebene des Haltens eines Wörterbuchs verfolgen, wie Sie in Ihrem Beispiel haben. Alles, was Sie in Ihrem Anruf tun, ist: feuern Sie das Ereignis ab.

+0

Aber Sie müssen immer noch überprüfen, wenn das Ereignis ausgelöst wird, dass Sie Beobachter haben, wenn Sie nicht haben Sie einige nette 'NullReferenceException' – Sidewinder94

+1

nicht, wenn Sie immer mindestens einen Listener haben: event EventHandler MyEvent = (s, e) => {}; –

+0

Nun nahm ich die Gewohnheit, in diesen Fällen nach Null zu überprüfen :) Aber ja, das ist eine andere Möglichkeit, es zu betrachten – Sidewinder94