Im Konstruktor eines Objekts, Listener
, nehmen wir ein Argument und abonnieren eines seiner Ereignisse. Wenn nach dem Abonnieren des Ereignisses eine Exception innerhalb des Konstruktors ausgelöst wird, wird die Methode OnSomethingChanged()
immer noch aufgerufen, wenn das Ereignis ausgelöst wird - auch wenn das Objekt nicht erfolgreich erstellt wurde und, soweit mir bekannt ist, keine Instanz existiert.
Jetzt kann ich das beheben, indem ich das Design offensichtlich etwas neu faktorisiere, aber mich interessiert eher, warum eine Instanzmethode aufgerufen wird, obwohl der Konstruktor nicht erfolgreich abgeschlossen wurde? Wenn die Methode irgendwelche lokalen Variablen verwendet, die vor der Ausnahme noch nicht initialisiert wurden, dann geht es offensichtlich um BOOM!
%Vor%Wenn eine Ausnahme von einem Konstruktor geworfen wird, bedeutet dies, dass eine Instanz möglicherweise in einem unvollständigen Zustand endet. Dadurch wird die Instanz nicht daran gehindert, erstellt und im Speicher gespeichert zu werden (wie dies vor geschieht) sein Konstruktor wird aufgerufen).
Außerdem wurde der Event-Handler bereits an die Zeit gebunden, zu der Sie die Exception werfen. Wenn Sie also das Ereignis auslösen, wird der Handler aufgerufen.
Um den ersten Punkt schnell zu veranschaulichen, wenn Sie Listener
ein Feld gegeben haben, das in seinem Konstruktor initialisiert werden soll, dann haben Sie versucht, es nach dem Auslösen der Ausnahme zu initialisieren (was offensichtlich nicht funktioniert):
Und dann versucht, in seinem OnSomethingChanged
-Handler darauf zuzugreifen:
Unabhängig davon, wie Sie new Listener(...)
aufrufen, wäre die Ausgabe
einfach weil der Listener keine Chance hatte, sein foo
-Feld zu initialisieren. Obwohl es nicht vollständig initialisiert wurde, ist es immer noch ein komplettes Objekt in Bezug auf die Zuweisung.
Tags und Links .net c# constructor exception event-handling