2010-06-11 5 views
8

In meinen Dispose-Methoden (wie die unten), jedes Mal, wenn ich SomeObj.Dispose() aufrufen möchte, habe ich auch eine Überprüfung für someObj! = Null.Entsorgen der Mitglieder, die IDisposable implementieren

Ist das wegen schlechten Designs meinerseits? Ist es ein saubererer Weg, sicherzustellen, dass Dispose von allen Mitgliedern (die IDisposable implementieren), die in einem Objekt verwendet werden, aufgerufen wird, ohne ein Risiko der NullReference-Ausnahme zu haben?

protected void Dispose(bool disposing) 
     { 
      if (disposing) 
      { 
       if (_splitTradePopupManager != null) 
       { 
        _splitTradePopupManager.Dispose(); 
       } 
      } 
     } 

Vielen Dank für Ihr Interesse.

Antwort

4

Vielleicht hat jemand anderes läuten kann in diesem, aber ich persönlich denke nicht, dass es ein Designfehler ist - nur der sicherste Weg, es zu tun.

Das heißt, ist nichts mehr im Wege stehen Ihre null Prüfung und Dispose Anruf in einer bequemen Methode Verpackung:

protected void Dispose(bool disposing) 
{ 
    if (disposing) 
    { 
     DisposeMember(_splitTradePopupManager); 
     DisposeMember(_disposableMember2); 
     DisposeMember(_disposableMember3); 
    } 
} 

Als zusätzlichen:

private void DisposeMember(IDisposable member) 
{ 
    if (member != null) 
     member.Dispose(); 
} 

Dann wird Ihr Dispose Methode ein wenig sauberer aussehen könnte Bonus, dies löst auch eine mögliche Race-Bedingung in Ihrem ursprünglichen Code. Bei Ausführung in einem Multithread-Kontext kann das Muster if (_field != null) _field.Dispose() zu einem NullReferenceException führen, wenn _field zwischen der Überprüfung und der Entsorgung auf null gesetzt ist (selten, aber möglich). Übergeben _field als ein Argument für eine Methode wie DisposeMember kopiert den Verweis auf eine lokale Variable in der Methode, diese Möglichkeit zu eliminieren, unwahrscheinlich wie es ist.

+1

Einverstanden damit nicht ein Designfehler. Vielleicht bin ich übervorsichtig, aber ich bevorzuge einen Null-Check, selbst wenn ich weiß, dass das Objekt bei Einwegartikeln nie null sein wird. –

+0

@ccomet: +1, ich habe das gleiche Denken (übervorsichtig) im Hinterkopf, während ich Dispose() für ein Objekt anrufe. –

0

Nur Sie kennen die Antwort auf dieses!

Ohne Ihre gesamte Klasse zu sehen, ist es für jeden anderen schwierig zu sagen, ob es möglich ist, dass diese Mitglieder jemals null sein werden, wenn aufgerufen wird.

(Natürlich in der Regel möglich, es ist immer für ein Referenztyp oder Nullable-Wertetyp null zu sein, so ist es wahrscheinlich eine gute Praxis immer die Null-Kontrollen sowieso, umfassen.)

0

Die einzige andere Option, die ich mir vorstellen könnte wäre, eine DisposeParameter Hilfsmethode zu erstellen, die ein Objekt als Parameter hat und nur prüft, ob es null ist und ansonsten Dispose. Auf diese Weise benötigen Sie nur eine Codezeile, um darüber zu verfügen, aber ich bin mir nicht sicher, ob es dadurch lesbarer wird.

-1

Versuchen Sie es.

protected void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      //for all members.. 
      if (null != member && member is IDisposible) 
      { 
       member.Dispose(); 
      } 
     } 
    } 
+0

Ich bin mir nicht sicher, ob ich verstehe, was Sie hier vorschlagen. –

+0

kann jemand die negative Stimme rechtfertigen? –

+4

Es war nicht ich, aber zu überprüfen, ob das Mitglied ein 'IDisposable' ist, ist ein bisschen albern, weil ein Aufruf von' member.Dispose() 'nicht kompilieren würde, wenn' member' kein Wegwerf-Typ wäre. – Steven

9

Ich mag @ Dan Tao-Lösung, aber es ist viel besser als eine Erweiterung Methode, imo:

public static void SafeDispose(this IDisposable obj) 
{ 
    if (obj != null) 
     obj.Dispose(); 
} 

Jetzt können Sie nur member.SafeDispose() für ein beliebiges IDisposable in Ihrem Programm, ohne Sorgen. :)

+0

Das wird nicht eine Null-Referenz Ausnahme werfen, wenn es versucht, die Erweiterungsmethode aufzurufen? Edit-- Ich schrieb eine schnelle Test-App, und es funktioniert super! –

+0

Nein, wird es nicht. Ich habe einen ähnlichen Ansatz in einem Projekt verwendet (DisposeIfNotNull()). –

+2

Nein! Da der Punktoperator für eine statische Methode nur syntaktischer Zucker ist, funktioniert es gut. :) – tzaman

Verwandte Themen