Einstellen von Objekten zu Null / Nichts nach Gebrauch in .NET

stimmen
173

Wenn Sie alle Objekte gesetzt null( Nothingin VB.NET) , wenn Sie mit ihnen fertig sind?

Ich verstehe , dass in .NET ist es wichtig , von allen Instanzen von Objekten zu verfügen, die die Implementierung IDisposableSchnittstelle einiger Ressourcen freizugeben , obwohl das Objekt noch etwas sein kann , nachdem es (daher das angeordnet ist isDisposedEigentum in Form), so dass ich davon ausgehen , es kann immer noch wohnen Speicher oder zumindest teilweise ?

Ich weiß auch, dass, wenn ein Objekt den Gültigkeitsbereich geht es dann zur Abholung bereit für den nächsten Durchlauf des Garbage Collector markiert ist (obwohl diese Zeit in Anspruch nehmen).

Also in diesem Sinne es Einstellung wird nulldas System die Freigabe der Speicher zu beschleunigen , da es nicht funktionieren hat , dass es nicht mehr in diesem Bereich und sind sie irgendwelche schlechten Nebenwirkungen?

MSDN-Artikel tun dies nie Beispiele in und zur Zeit mache ich das, weil ich nicht um den Schaden zu sehen. Ich habe über eine Mischung aus Meinungen kommen jedoch so keine Kommentare nützlich sind.

Veröffentlicht am 05/08/2008 um 21:14
quelle vom benutzer
In anderen Sprachen...                            


13 antworten

stimmen
66

Karl ist absolut richtig, besteht keine Notwendigkeit, Objekte zu null nach Gebrauch einzustellen. Wenn ein Objekt implementiert IDisposable, so stellen Sie sicher , dass Sie anrufen , IDisposable.Dispose()wenn Sie mit dem Objekt fertig sind (in einem eingewickelt try.. finallyoder einen using()Block). Aber auch wenn Sie anrufen kann mich nicht erinnern Dispose(), die finaliser Methode für das Objekt sollte sein Aufruf Dispose()für Sie.

Ich dachte, das ist eine gute Behandlung wurde:

Graben in IDisposable

und das

Das Verständnis IDisposable

Es gibt keinen Punkt , bei dem Versuch , die GC und seine Management - Strategien auf den zweiten zu erraten , weil es die automatische Optimierung und undurchsichtig ist. Es gab eine gute Diskussion über das Innenleben mit Jeffrey Richter auf Dot Net Rock hier: Jeffrey Richter auf dem Windows - Speichermodell und Richters Buch CLR via C # Kapitel 20 hat eine große Behandlung:

Beantwortet am 05/08/2008 um 21:56
quelle vom benutzer

stimmen
33

Ein weiterer Grund, zu vermeiden Objekte auf Null gesetzt wird, wenn Sie fertig sind mit ihnen ist, dass es sie tatsächlich länger am Leben halten können.

z.B

void foo()
{
    var someType = new SomeType();
    someType.DoSomething();
    // someType is now eligible for garbage collection         

    // ... rest of method not using 'someType' ...
}

ermöglicht die durch sometype genannte Objekt „DoSomething“ nach dem Aufruf zu GC'd aber

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 manchmal das Leben bis zum Ende des Verfahrens Objekt halten. Der JIT wird in der Regel die Zuordnung wegoptimiert auf Null , so dass beiden Teile des Codes am Ende das gleiche sind.

Beantwortet am 15/08/2008 um 15:43
quelle vom benutzer

stimmen
15

Nein nicht null Objekte. Sie können überprüfen http://codebetter.com/blogs/karlseguin/archive/2008/04/27/foundations-of-programming-pt-7-back-to-basics-memory.aspx für weitere Informationen, aber die Dinge Einstellung zu null wird nichts tun, außer schmutzigen Code.

Beantwortet am 05/08/2008 um 21:23
quelle vom benutzer

stimmen
7

Im Allgemeinen gibt es keine Notwendigkeit Objekte nach dem Gebrauch auf null, aber in einigen Fällen finde ich, es ist eine gute Praxis.

Wenn ein Objekt implementiert IDisposable und wird in einem Feld gespeichert, ich denke, es ist gut, es auf null, nur um zu vermeiden, dass das angeordnete Objekt. Die Fehler der folgenden Art können schmerzhaft sein:

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

Es ist gut, das Feld auf null, nachdem sie, und eine NullPtrEx direkt an der Linie angeordnet wird, wo das Feld wieder verwendet wird. Andernfalls könnten Sie in einen kryptischen Fehler auf der ganzen Linie laufen (je nach genau das, was DoSomething tut).

Beantwortet am 09/08/2008 um 12:16
quelle vom benutzer

stimmen
7

Ebenfalls:

using(SomeObject object = new SomeObject()) 
{
  // do stuff with the object
}
// the object will be disposed of
Beantwortet am 05/08/2008 um 21:37
quelle vom benutzer

stimmen
6

Die Chancen stehen gut, dass Ihr Code nicht fest strukturiert ist genug , wenn Sie das Bedürfnis zu fühlen nullVariablen.

Es gibt eine Reihe von Möglichkeiten, um den Umfang einer Variablen zu begrenzen:

Wie bereits erwähnt von Steve Tranby

using(SomeObject object = new SomeObject()) 
{
  // do stuff with the object
}
// the object will be disposed of

In ähnlicher Weise können Sie einfach geschweiften Klammern verwenden:

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

Ich finde, dass geschweifte Klammern ohne „heading“ wirklich sauber aus dem Code und dazu beitragen, dass es verständlicher.

Beantwortet am 09/08/2008 um 13:13
quelle vom benutzer

stimmen
5

Im Allgemeinen keine Notwendigkeit, auf null gesetzt. Aber nehmen wir an Sie eine Reset-Funktion in der Klasse haben.

Dann könnten Sie tun, weil Sie wollen nicht zweimal rufen entsorgen, da ein Teil der Entsorgung nicht korrekt implementiert werden kann und System.ObjectDisposed Ausnahme auslösen.

private void Reset()
{
    if(_dataset != null)
    {
       _dataset.Dispose();
       _dataset = null;
    }
    //..More such member variables like oracle connection etc. _oraConnection
 }
Beantwortet am 17/04/2012 um 09:55
quelle vom benutzer

stimmen
4

Das einzige Mal, wenn Sie eine Variable sollten auf null ist, wenn die Variable nicht außerhalb des Bereichs geht und Sie nicht mehr auf die Daten zugeordnet müssen. Ansonsten gibt es keine Notwendigkeit.

Beantwortet am 05/08/2008 um 21:32
quelle vom benutzer

stimmen
3

diese Art von „besteht keine Notwendigkeit, Objekte zu null nach dem Gebrauch zu setzen“ ist nicht ganz korrekt. Es gibt Zeiten, müssen Sie die Variable auf NULL, nachdem sie zu entsorgen.

Ja, Sie sollten immer anrufen .Dispose()oder .Close()auf alles , was es hat , wenn Sie fertig sind. Sei es Griffe, Datenbankverbindungen oder Wegwerf-Objekte einreichen.

Getrennt von dem ist das sehr praktisch Muster von LazyLoad.

Sagen , ich habe und instanziiert ObjAvon class A. Class Ahat eine öffentliche Eigenschaft namens PropBvon class B.

Intern PropBverwendet die privaten Variable von _Bund standardmäßig auf null. Wenn PropB.Get()verwendet wird, überprüft es, ob _PropBnull ist und wenn es ist, öffnet die benötigten Ressourcen , um eine instanziiert Bin _PropB. Er kehrt dann _PropB.

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

Wo die Notwendigkeit zu null kommt in ist , wenn Sie in irgendeiner Weise zurückgesetzt oder eine Änderung , dass der Inhalt _PropBdas Kind der vorherigen Werte waren A, müssen Sie verfügen und null aus , _PropBso kann LazyLoad setzen Sie den richtigen Wert , wenn der Code zu holen es erfordert.

Wenn Sie nur tun _PropB.Dispose()für LazyLoad und erwarten , kurz nach der NULL - Prüfung erfolgreich zu sein, wird es nicht null sein, und Sie werden auf veralteten Daten suchen werden. In der Tat, müssen Sie es nach null , Dispose()nur um sicher zu sein.

Ich wünsche , dass es anders, aber ich habe jetzt bekam Code , um dieses Verhalten nach einer ausstellenden Dispose()auf ein _PropBund außerhalb der rufenden Funktion, die das Entsorgen tat (und damit fast den Gültigkeitsbereich), der private prop ist noch nicht null, und die veralteten Daten sind immer noch da.

Schließlich wird null die angeordneten Eigenschaft, aber das ist schon nicht deterministisch aus meiner Sicht.

Der Kern Grund, wie dbkk anspielt ist , dass der übergeordnete Container ( ObjAmit PropB) wird die Instanz des Halten _PropBim Umfang trotz der Dispose().

Beantwortet am 11/04/2012 um 02:12
quelle vom benutzer

stimmen
1

Werfen Sie einen Blick auf diese Artikel auch: http://www.codeproject.com/KB/cs/idisposable.aspx

Zum größten Teil hat ein Objekt auf null Einstellung keine Wirkung. Das einzige Mal, sollten Sie sicher sein, dies zu tun ist, wenn Sie mit einem „großen Objekt“ arbeiten, die eine größer als 84K in der Größe ist (wie Bitmaps).

Beantwortet am 17/08/2008 um 05:46
quelle vom benutzer

stimmen
1

Es gibt einige Fälle, in denen es sinnvoll, Verweise auf null macht. Zum Beispiel, wenn Sie eine Sammlung gerade schreiben - wie eine Prioritätswarteschlange - und von Ihrem Vertrag, sollten Sie nicht die Objekte lebendig für die Kunden werden zu halten, nachdem die Client sich aus der Warteschlange entfernt.

Aber diese Art der Sache ist nur wichtig in langlebigen Sammlungen. Wenn die Warteschlange wird nicht das Ende der Funktion überleben sie erstellt wurde in, dann zählt es eine ganze Menge weniger.

Auf insgesamt, sollten Sie wirklich nicht stören. Lassen Sie die Compiler und GC ihre Arbeit tun, damit Sie Sie tun können.

Beantwortet am 05/08/2008 um 21:46
quelle vom benutzer

stimmen
0

Ich glaube , durch Gestaltung des GC Implementierer, Sie nicht können beschleunigen GC mit nullification. Ich bin sicher , sie würden Sie es vorziehen , nicht selbst mit Sorge wie / wann GC läuft - behandeln sie wie diese allgegenwärtige Wesen zu schützen und über die und aus für Sie beobachten ... (Bögen mit gesenktem Kopf, die Faust in den Himmel wirft) .. .

Ich persönlich oft explizit Variablen auf null gesetzt, wenn ich mit ihnen als eine Form der Selbstdokumentation fertig bin. Ich erkläre nicht, verwenden, dann später auf null gesetzt - ich null unmittelbar nach dem sie nicht mehr benötigt werden. Ich sage ausdrücklich: „Ich bin offiziell fertig mit dir ... weg ...“

Ist zunichte gemacht notwendig in einer GC'd Sprache? Nein . Ist es hilfreich für die GC? Vielleicht ja, vielleicht nein, wissen nicht , für bestimmte, von Entwurf , den ich wirklich nicht, und außerhalb meiner Kontrolle mit dieser Version oder dass könnten künftige GC - Implementierungen ändern , um die Antwort Antwort der unabhängig von heute kontrollieren kann. Plus , wenn / wenn nulling optimiert heraus , es ist wenig mehr als eine Phantasie Kommentar , wenn man so will.

Ich denke , wenn es meine Absicht klarer auf den nächsten armen Narren, der in meinen Fußstapfen folgt macht, und wenn es „könnte“ potenziell GC manchmal helfen, dann ist es wert , es zu mir. Meistens macht es mich ordentlich und klar fühlen und Mongo mag ordentlich und klar fühlen. :)

Ich sehe es so: Programmiersprachen existieren Menschen geben andere Menschen eine Vorstellung von Vorsatz und einen Compiler einer Auftragsanforderung von dem, was tun lassen - der Compiler wandelt diese Anforderung in eine andere Sprache (manchmal mehr) für ein CPU - die CPU (s) konnte einen Schrei geben, welche Sprache Sie verwendet, Ihre Einstellungen auf der Registerkarte, Kommentare, stilistische Akzente, Variablennamen usw. - eine CPU alles dreht sich um den Bitstrom, der ihm sagt, was registriert und OP-Codes und Speicherplätze twiddle. Viele Dinge im Code geschrieben hat, in nicht konvertieren, was durch die CPU in der Folge verbraucht werden wir angegeben. Unsere C, C ++, C #, Lisp, Babel, Assembler oder was auch immer ist Theorie eher als die Realität, als eine Erklärung der Arbeit geschrieben. Was Sie sehen, ist nicht das, was Sie bekommen, ja, auch in Assemblersprache.

Ich mache die Mentalität der „unnötige Dinge“ (wie Leerzeilen) verstehen „sind nichts anderes als Lärm und Unordnung up-Code.“ Das war ich früher in meiner Karriere; Ich erhalte total, dass. An dieser Stelle lehne ich mich auf das, was Code klarer macht. Es ist nicht wie ich hinzufüge, sogar 50 Zeilen von „Lärm“ zu meinen Programmen - es ist ein paar Zeilen hier oder dort.

Es gibt Ausnahmen von jeder Regel. In Szenarien mit flüchtigen Speicher, ein statischer Speicher, Rennbedingungen, Singletons, Verwendung von „veralteten“ Daten und alle diese Art von rot, das ist etwas anderes: Sie müssen Ihre eigenen Speicher, Sperren und zunichte gemacht als apropos verwalten, da der Speicher nicht Teil ist das GC'd Universum - hoffentlich jeder versteht, dass. Der Rest der Zeit mit GC'd Sprachen ist es eine Frage des Stils und nicht aus Notwendigkeit oder eine garantierte Leistungssteigerung.

Am Ende des Tages stellen Sie sicher, Sie verstehen, was für GC berechtigt ist und was nicht; sperren, verfügen, und in geeigneter Weise zunichte machen; Wachs drauf, Wachs runter; Einatmen Ausatmen; und für alles, was ich sagen: Wenn es fühlt sich gut an, es zu tun. Ihre Ergebnisse können variieren ... wie es sein sollte ...

Beantwortet am 10/05/2016 um 13:07
quelle vom benutzer

stimmen
-1

Einige Objekt annehmen , das .dispose()Verfahren, das die Ressource Kräfte aus dem Speicher entfernt werden.

Beantwortet am 05/08/2008 um 21:21
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more