Festlegen von Objekten auf Null / Nichts nach der Verwendung in .NET

  • Sollten Sie alle Objekte auf null (Nothing in VB.NET) setzen, wenn Sie damit fertig sind?

    Ich verstehe, dass es in .NET unerlässlich ist, alle Instanzen von Objekten zu beseitigen, die die Schnittstelle IDisposable implementieren, um einige Ressourcen freizugeben, obwohl das Objekt noch etwas enthalten kann entsorgt (daher die isDisposed -Eigenschaft in Formularen), also gehe ich davon aus, dass sie sich noch im Speicher befinden kann oder zumindest teilweise?

    Ich weiß auch, dass, wenn ein Objekt ausfällt Dann wird der Bereich für die Sammlung für den nächsten Durchlauf des Speicherbereinigers markiert (obwohl dies Zeit in Anspruch nehmen kann).

    Daher wird die Geschwindigkeit auf null gesetzt Das System muss den Speicher freigeben, da es nicht herausfinden muss, dass es nicht mehr im Gültigkeitsbereich liegt. Gibt es schlechte Nebenwirkungen?

    MSDN-Artikel tun dies in den Beispielen und nie Im Moment mache ich das, weil ich den Schaden nicht sehen kann. Ich bin jedoch auf eine Mischung von Meinungen gestoßen, so dass Kommentare nützlich sind.

    04 May 2012
    mattytommoSkooz
12 answers
  • Karl ist absolut korrekt. Objekte müssen nach der Verwendung nicht auf Null gesetzt werden. Wenn ein Objekt IDisposable implementiert, stellen Sie sicher, dass Sie IDisposable.Dispose() aufrufen, wenn Sie mit diesem Objekt fertig sind (in einen try .. finally oder einen using() -Block). Aber auch wenn Sie nicht daran denken, Dispose() aufzurufen, sollte die Finalizer-Methode für das Objekt Dispose() für Sie aufrufen.

    Ich dachte, das wäre eine gute Behandlung:

    In IDisposable einsteigen

    und das

    IDisposable verstehen

    Es gibt keinen Grund, den GC zu erraten und seine Managementstrategien, weil es sich selbst abstimmt und undurchsichtig ist. Es gab eine gute Diskussion über das Innenleben mit Jeffrey Richter auf Dot Net Rocks: Jeffrey Richter über das Windows-Speichermodell und Richters CLR über C # Kapitel 20 ist eine großartige Behandlung:

    27 January 2013
    KevBrian
  • Ein weiterer Grund, um zu vermeiden, dass Objekte auf Null gesetzt werden, wenn Sie damit fertig sind, ist, dass sie tatsächlich länger am Leben bleiben können.

    zB

     void foo()
    {
        var someType = new SomeType();
        someType.DoSomething();
        // someType is now eligible for garbage collection         
    
        // ... rest of method not using 'someType' ...
    }
     

    wird das Objekt erlauben, das von someType referenziert wird Wenn Sie nach dem Aufruf von "DoSomething" GC'd erhalten,

     void foo()
    {
        var someType = new SomeType();
        someType.DoSomething();
        // someType is NOT eligible for garbage collection yet
        // because that variable is used at the end of the method         
    
        // ... rest of method not using 'someType' ...
        someType = null;
    }
     

    kann das Objekt manchmal bis zum Ende der Methode. Die JIT optimiert normalerweise die Zuweisung auf null. So sind beide Codebits gleich.

    15 August 2008
    Wilka
  • Nein, keine Objekte. Sie können http://codebetter.com/blogs/karlseguin/archive/2008/04/27/foundations-of-programming-pt-7-back-to-basics-memory.aspx für weitere Informationen Informationen, aber das Festlegen von Dingen auf Null bewirkt nichts, außer Ihren Code zu verschmutzen.

    06 August 2008
    mrdenny
  • Im Allgemeinen ist es nicht erforderlich, Objekte nach der Verwendung auf Null zu setzen, aber in manchen Fällen halte ich es für eine gute Praxis.

    Wenn ein Objekt IDisposable implementiert und gespeichert wird In einem Feld finde ich es gut, es auf Null zu setzen, nur um zu vermeiden, dass das abgelegte Objekt verwendet wird. Die Fehler der folgenden Art können schmerzhaft sein:

     this.myField.Dispose();
    // ... at some later time
    this.myField.DoSomething();
     

    Es ist gut, das Feld nach der Beseitigung auf Null zu setzen, und Holen Sie sich ein NullPtrEx direkt in der Zeile, in der das Feld erneut verwendet wird. Andernfalls könnte es zu einem kryptischen Fehler kommen (abhängig davon, was DoSomething genau macht).

    09 August 2008
    dbkk
  • Außerdem:

     using(SomeObject object = new SomeObject()) 
    {
      // do stuff with the object
    }
    // the object will be disposed of
     
    06 August 2008
    Steve Tranby
  • Die Wahrscheinlichkeit ist groß, dass Ihr Code nicht fest genug strukturiert ist, wenn Sie das Bedürfnis haben, null -Variablen zu verwenden.

    Es gibt a Anzahl der Möglichkeiten, den Gültigkeitsbereich einer Variablen einzuschränken:

    Wie von Steve Tranby

     erwähnt. && 2&&] 

    Ebenso können Sie geschweifte Klammern verwenden:

     {
        // Declare the variable and use it
        SomeObject object = new SomeObject()
    }
    // The variable is no longer available
     

    Ich finde, dass geschwungene Klammern ohne "Überschrift" verwendet werden, um den Code wirklich zu bereinigen und ihn verständlicher zu machen.

    09 August 2008
    mbillard
  • Im Allgemeinen muss kein Wert auf null gesetzt werden. Angenommen, Sie verfügen über eine Reset-Funktion in Ihrer Klasse.

    Dann könnten Sie dies tun, da Sie dispose nicht zweimal aufrufen möchten, da einige der Dispose-Funktionen möglicherweise nicht korrekt implementiert sind System.ObjectDisposed-Ausnahme auslösen.

     private void Reset()
    {
        if(_dataset != null)
        {
           _dataset.Dispose();
           _dataset = null;
        }
        //..More such member variables like oracle connection etc. _oraConnection
     }
     
    17 April 2012
    Munish Goyal
  • Sie sollten eine Variable nur dann auf null setzen, wenn die Variable nicht außerhalb des Gültigkeitsbereichs liegt und Sie die damit verknüpften Daten nicht mehr benötigen. Ansonsten besteht keine Notwendigkeit.

    06 August 2008
    Bob
  • diese Art von "Es ist nicht erforderlich, Objekte nach Gebrauch auf Null zu setzen", ist nicht ganz genau. Es kann vorkommen, dass Sie die Variable NULL NULLen müssen, nachdem Sie sie abgelegt haben.

    Ja, sollten Sie IMMER .Dispose() oder .Close() für alles aufrufen, wenn Sie fertig sind. Sei es Dateihandles, Datenbankverbindungen oder Einwegobjekte.

    Unabhängig davon ist das sehr praktische Muster von LazyLoad.

    Sagen Sie ich haben und ObjA von class A instanziiert. Class A besitzt eine öffentliche Eigenschaft mit dem Namen PropB von class B.

    Intern verwendet PropB die private Variable von _B und hat den Standardwert null. Wenn PropB.Get() verwendet wird, wird geprüft, ob _PropB null ist, und falls ja, werden die Ressourcen geöffnet, die zum Instantiieren eines B in _PropB erforderlich sind. Dann wird _PropB zurückgegeben.

    Nach meiner Erfahrung ist dies ein wirklich nützlicher Trick.

    Wo das Erfordernis der Nullung ist Wenn Sie A auf irgendeine Weise zurücksetzen oder ändern, dass der Inhalt von _PropB das untergeordnete Element der vorherigen Werte von A war, müssen Sie _PropB entsorgen und nullen, damit LazyLoad zurückgesetzt werden kann, um den richtigen Wert abzurufen WENN der Code dies erfordert.

    Wenn Sie nur _PropB.Dispose() ausführen und kurz darauf erwarten, dass die erfolgreiche Prüfung von LazyLoad erfolgreich ist, ist sie nicht null und Sie werden es tun Blick auf veraltete Daten. In der Tat müssen Sie es nach Dispose() auf Null setzen, nur um sicher zu sein.

    Ich wünschte, es wäre anders, aber ich habe jetzt Code, der dieses Verhalten nach einem Dispose() Bei einer _PropB und außerhalb der aufrufenden Funktion, die die Dispose-Funktion ausgeführt hat (und somit fast außerhalb des Gültigkeitsbereichs), ist die private Eigenschaft immer noch nicht null und die veralteten Daten sind immer noch vorhanden.

    Irgendwann wird die disponierte Eigenschaft auf null gesetzt, aber das ist aus meiner Sicht nicht deterministisch.

    Der Hauptgrund, da dbkk anspielt, ist der übergeordnete Container (ObjA mit PropB) hält die Instanz von _PropB trotz Dispose() im Gültigkeitsbereich.

    09 June 2012
    Siddharth Rout
  • Sehen Sie sich auch diesen Artikel an: http: // www .codeproject.com / KB / cs / idisposable.aspx

    Das Festlegen eines Objekts auf null hat meist keine Auswirkung. Die einzige Zeit, zu der Sie sicher sein sollten, ist, wenn Sie mit einem "großen Objekt" arbeiten, das größer als 84 KB ist (z. B. Bitmaps).

    01 November 2008
    Scott Dorman