Umgang mit Ausnahmen im Konstruktor bei der Implementierung von IDisposable

8

Ich lese Ich muss IDisposable implementieren, wenn meine Klasse eine Mitgliedsvariable hat, die selbst IDisposable ist. Nun, ich implementiere IDisposable interface, weil meine Klasse ein Datenbankobjekt enthält ( db -Klassenmitglied), das IDisposable selbst ist:

%Vor%

Das Problem besteht in der Instanziierung von db member kann unter bestimmten Umständen fehlschlagen. Was muss ich tun, wenn die Exception im Konstruktor ausgelöst wird und das Datenbankobjekt nicht erstellt wird? Sollte ich die Ausnahme erneut auslösen oder vielleicht überprüfen, ob db != null in der InsertRecord-Methode?

    
ezpresso 15.12.2011, 21:17
quelle

5 Antworten

3

Wenn Ihr Konstruktor eine Ausnahme auslöst, erhält der Consumer Ihres Codes niemals einen Verweis auf eine Instanz Ihrer Klasse. Der teilweise initialisierte Klassenspeicher wird schließlich gesammelt und Dispose wird nicht aufgerufen.

Ich würde generell empfehlen, einen Vorgang, der aufgrund von äußeren Umständen (und nicht aufgrund von Missbrauch, wie ein ungültiger Parameterwert) fehlschlagen kann, auf eine separate Methode wie "Verbinden" zu verschieben.

    
Dan Bryant 15.12.2011 21:21
quelle
2

Idealerweise sollten Sie im Konstruktor keine "Arbeit" ausführen. Die Arbeit im Konstruktor sollte eigentlich Objektverweise verknüpfen. Auf diese Weise können Sie diese Klasse testen, indem Sie stattdessen Scheinklassen anschließen.

Versuchen Sie es stattdessen:

%Vor%     
Andy Christianson 15.12.2011 21:21
quelle
2

Es sieht so aus als ob du nichts tun musst.

Wenn Ihr Konstruktionsprozess unterbrochen wird, wird die Ressource nicht erstellt. In den meisten Anwendungsszenarien (das liegt außerhalb Ihrer Klasse) wird das Dispose () niemals aufgerufen. Aber selbst wenn es so ist, ist Ihr if (db != null) Code genug für einen Wächter.

Einige kleinere Punkte:

  • Die db = null; innerhalb von Dispose () ist sinnlos.
  • InsertRecord() sollte mit if (db != null) beginnen
Henk Holterman 15.12.2011 21:23
quelle
1

Sie sollten nur Ausnahmen erfassen, die Sie behandeln können. Aus dem Code scheint es, dass das Initialisieren der Variablen db möglicherweise anzeigt, dass ein Problem bei der Kommunikation mit Ihrem Datenbankserver besteht.

Ich schlage vor, den Code so zu belassen, wie er ist, und an einem zentralen Ort Ausnahmen zu behandeln, z. B. das Ereignis Application_Error in der Datei Global.asax oder das Ereignis, das das CommissionModel initialisiert.

    
Novus 15.12.2011 21:21
quelle
1

Wenn zwischen dem Zeitpunkt, an dem der Konstruktor eine Ressource anfordert, und der Zeit, zu der er an die Anwendung zurückgegeben wird, keine Ausnahme (*) auftreten kann, müssen Sie sich keine Sorgen machen.

Wenn es möglich ist, dass unter solchen Umständen eine Ausnahme auftreten könnte, würde ich ein Muster vorschlagen wie:

%Vor%

(*) Es ist fast immer möglich, dass eine ThreadAbortException auftritt, wenn ein bösartiger Oger Tread.Abort auf Ihrem Code aufruft, aber in diesem Fall gibt es wirklich nichts zu tun.

    
supercat 16.12.2011 00:22
quelle

Tags und Links