
Θα πρέπει να ορίσετε όλα τα αντικείμενα για να `null`( `Nothing`σε VB.NET), αφού έχετε τελειώσει μαζί τους;


Καταλαβαίνω ότι το .NET είναι απαραίτητο να διαθέσει τυχόν περιπτώσεις των αντικειμένων που υλοποιούν το `IDisposable`interface για να απελευθερώσει κάποιους πόρους, αν το αντικείμενο μπορεί ακόμα να είναι κάτι μετά την διάθεση (εξ ου και η `isDisposed`ιδιοκτησία σε μορφές), οπότε υποθέτω ότι μπορεί ακόμα να κατοικούν στη μνήμη ή τουλάχιστον εν μέρει;


Γνωρίζω, επίσης, ότι όταν ένα αντικείμενο βγαίνει από το πεδίο εφαρμογής είναι συνέχεια σημειώνεται για τη συλλογή έτοιμοι για το επόμενο πέρασμα του συλλέκτη σκουπιδιών (αν και αυτό μπορεί να πάρει χρόνο).


Έτσι, με αυτό το πνεύμα θα ρύθμιση για `null`την επιτάχυνση του συστήματος απελευθερώνοντας τη μνήμη, καθώς δεν πρέπει να καταλάβεις ότι δεν είναι πλέον στο πεδίο εφαρμογής είναι και ότι οποιεσδήποτε κακές παρενέργειες;


MSDN άρθρα ποτέ δεν το κάνουμε αυτό με παραδείγματα και σήμερα κάνω αυτό, όπως δεν μπορώ να δω τη ζημιά. Ωστόσο, έχω έρθει σε ένα μίγμα απόψεων, ώστε τυχόν παρατηρήσεις είναι χρήσιμες.

 
Ρύθμιση αντικείμενα στην Null / Τίποτα μετά τη χρήση στην ΝΕΤ
=============================================================



Karl είναι απολύτως σωστό, δεν υπάρχει ανάγκη να ρυθμίσετε αντικείμενα για να άκυρη μετά τη χρήση. Αν ένα αντικείμενο υλοποιεί `IDisposable`, απλά φροντίστε να καλέσετε `IDisposable.Dispose()`όταν τελειώσετε με αυτό το αντικείμενο (τυλιγμένο σε μια `try`.. `finally`, ή, ένα `using()`μπλοκ). Αλλά ακόμα και αν δεν θυμάστε να καλέσετε `Dispose()`, η μέθοδος finaliser στο αντικείμενο θα πρέπει να καλούν `Dispose()`για εσάς.


Σκέφτηκα ότι αυτό ήταν μια καλή θεραπεία:


[Σκάβοντας σε IDisposable](http://msdn.microsoft.com/en-us/magazine/cc163392.aspx)


και αυτό 


[Κατανόηση IDisposable](http://web.archive.org/web/20090426210049/www.marcclifton.com/tabid/79/Default.aspx)


Δεν υπάρχει κανένα νόημα να προσπαθούμε να μαντέψουμε το δεύτερο το GC και τις στρατηγικές διαχείρισης της επειδή είναι μόνος ρύθμιση και αδιαφανές. Υπήρξε μια καλή συζήτηση για τις εσωτερικές διεργασίες με Jeffrey Ρίχτερ στο Dot Net Rocks εδώ: [Jeffrey Ρίχτερ στο μοντέλο μνήμης των Windows](http://www.dotnetrocks.com/default.aspx?showNum=361) βιβλίου και Richters [CLR μέσω C #](http://www.compman.co.uk/scripts/browse.asp?ref=747022) κεφάλαιο 20 έχει μια πολύ καλή θεραπεία:

 

Μερικοί αντικείμενο ας υποθέσουμε ότι η `.dispose()`μέθοδος η οποία αναγκάζει τον πόρο που πρέπει να αφαιρεθεί από τη μνήμη.

 

Όχι δεν null αντικείμενα. Μπορείτε να ελέγξετε έξω <http://codebetter.com/blogs/karlseguin/archive/2008/04/27/foundations-of-programming-pt-7-back-to-basics-memory.aspx> για περισσότερες πληροφορίες, αλλά και τον καθορισμό πράγματα με μηδενική δεν θα κάνει τίποτα, εκτός από βρώμικα τον κωδικό σας.

 

Η μόνη φορά που θα πρέπει να ορίσετε μια μεταβλητή για να null είναι όταν η μεταβλητή δεν βγαίνουν από το πεδίο εφαρμογής και δεν χρειάζεται πλέον τα δεδομένα που σχετίζονται με αυτό. Διαφορετικά δεν υπάρχει ανάγκη.

 

Επίσης:



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

```
 

Υπάρχουν κάποιες περιπτώσεις όπου έχει νόημα να null αναφορές. Για παράδειγμα, όταν γράφετε μια συλλογή - σαν μια ουρά προτεραιότητας - και από το συμβόλαιό σας, δεν θα πρέπει να είναι η διατήρηση των εν λόγω αντικειμένων ζωντανός για τον πελάτη αφού ο πελάτης τους έχει αφαιρεθεί από την ουρά.


Αλλά αυτό το είδος του πράγματος που έχει σημασία μόνο σε καιρό ζούσε συλλογές. Αν η ουρά δεν πρόκειται να επιβιώσει το τέλος της λειτουργίας που δημιουργήθηκε το, τότε μετράει ένα σωρό λιγότερο.


Σε σύνολο, που πραγματικά δεν θα πρέπει να ενοχλεί. Αφήστε το compiler και GC κάνουν τη δουλειά τους, ώστε να μπορείτε να το κάνετε δικό σας.

 

Σε γενικές γραμμές, δεν υπάρχει καμία ανάγκη να null αντικείμενα μετά τη χρήση, αλλά σε ορισμένες περιπτώσεις θεωρώ ότι είναι μια καλή πρακτική.


Αν ένα αντικείμενο υλοποιεί IDisposable και αποθηκεύεται σε ένα πεδίο, νομίζω ότι είναι καλό να το null, απλά για να αποφύγετε τη χρήση του μεταβίβασε αντικείμενο. Τα σφάλματα του παρακάτω είδους μπορεί να είναι επώδυνη:



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

```

Είναι καλό να null το πεδίο μετά την απόρριψη αυτή, και να πάρει το δικαίωμα NullPtrEx στη γραμμή όπου το πεδίο χρησιμοποιείται και πάλι. Διαφορετικά, μπορεί να τρέξει σε κάποιο αινιγματικό bug κάτω από τη γραμμή (ανάλογα με το τι ακριβώς κάνει doSomething).

 

Οι πιθανότητες είναι ότι ο κωδικός σας δεν είναι δομημένη αρκετά καλά, εάν αισθάνεστε την ανάγκη να *`null`*μεταβλητές.


Υπάρχουν διάφοροι τρόποι για να περιορίσει το πεδίο εφαρμογής μιας μεταβλητής:


Όπως αναφέρει ο **Steve Tranby**



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

```

Ομοίως, μπορείτε απλά να χρησιμοποιήσετε αγκύλες:



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

```

Θεωρώ ότι η χρήση αγκύλες χωρίς οποιαδήποτε «επικεφαλίδα» για να καθαρίσει πραγματικά τον κώδικα και να βοηθήσει να γίνει πιο κατανοητό.

 

Ένας άλλος λόγος για να αποφευχθεί ο καθορισμός αντικείμενα για να null όταν τελειώσετε με αυτούς είναι ότι μπορεί να τους κρατήσει πραγματικά ζωντανό για μεγαλύτερο χρονικό διάστημα. 


π.χ



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

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

```

θα επιτρέψει στο αντικείμενο που αναφέρεται από sometype να GC'd μετά την κλήση για να «doSomething», αλλά



```
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;
}

```

μπορεί μερικές φορές να κρατήσει το αντικείμενο ζωντανό μέχρι το τέλος της μεθόδου. Η [ΚΟΕ συνήθως θα βελτιστοποιηθεί μακριά την εκχώρηση σε null](http://blogs.msdn.com/clyon/archive/2004/12/01/273144.aspx) , έτσι ώστε τα δύο δυαδικά ψηφία του κωδικού καταλήγουν να είναι το ίδιο.

 

Ρίξτε μια ματιά σε αυτό το άρθρο, καθώς: <http://www.codeproject.com/KB/cs/idisposable.aspx>


Για το μεγαλύτερο μέρος, θέτοντας ένα αντικείμενο με μηδενική έχει καμία επίδραση. Η μόνη φορά που θα πρέπει να είναι σίγουρος για να το κάνει είναι εάν εργάζεστε με ένα «μεγάλο αντικείμενο», το οποίο είναι ένα μεγαλύτερο από 84K σε μέγεθος (όπως bitmaps).

 

αυτό το είδος της «δεν υπάρχει καμία ανάγκη να ρυθμίσετε αντικείμενα για να άκυρη μετά τη χρήση» δεν είναι απολύτως ακριβής. Υπάρχουν φορές που πρέπει να NULL τη μεταβλητή μετά την απόρριψη αυτή.


Ναι, θα πρέπει πάντα να καλέσετε `.Dispose()`ή `.Close()`για οτιδήποτε έχει όταν τελειώσετε. Είτε πρόκειται για αρχείο λαβές, συνδέσεις βάσης δεδομένων ή μιας χρήσης αντικείμενα.


Ξεχωριστό από αυτό το πολύ πρακτικό πρότυπο LazyLoad.


Πείτε έχω και τεκμηριώθηκε `ObjA`της `class A`. `Class A`έχει μια δημόσια περιουσία που ονομάζεται `PropB`του `class B`.


Εσωτερικά, `PropB`χρησιμοποιεί την ιδιωτική μεταβλητή `_B`και προεπιλογές σε null. Όταν `PropB.Get()`χρησιμοποιείται, ελέγχει για να δει αν `_PropB`είναι άκυρη και αν είναι, ανοίγει τους πόρους που απαιτούνται για την υπόσταση σε μια `B`σε `_PropB`. Στη συνέχεια επιστρέφει `_PropB`.


Για την εμπειρία μου, αυτό είναι ένα πραγματικά χρήσιμο κόλπο.


Όταν η ανάγκη για μηδενική μπαίνει είναι εάν επαναφέρετε ή να αλλάξετε μια κατά κάποιο τρόπο ότι το περιεχόμενο της `_PropB`ήταν το παιδί από τις προηγούμενες τιμές της `A`, θα πρέπει να Απορρίψτε ΚΑΙ null έξω `_PropB`έτσι LazyLoad να επαναφέρετε για να πάρει τη σωστή αξία εάν ο κωδικός απαιτεί αυτό.


Αν το μόνο που κάνουμε `_PropB.Dispose()`και λίγο μετά αναμένουμε η μηδενική ελέγχου για LazyLoad να πετύχει, δεν θα είναι μηδενική, και θα πρέπει να ψάχνει σε μπαγιάτικο δεδομένων. Στην πραγματικότητα, θα πρέπει να το null μετά από `Dispose()`ακριβώς για να είναι σίγουρος.


Εγώ σίγουρα ήθελα να ήταν διαφορετικά, αλλά έχω κωδικό στιγμή που εμφανίζουν αυτή τη συμπεριφορά μετά από ένα `Dispose()`σε ένα `_PropB`και εκτός της λειτουργίας κλήσης που έκανε την απόρριψη (και ως εκ τούτου σχεδόν έξω από το πεδίο εφαρμογής), ο ιδιωτικός στήριγμα εξακολουθεί να μην είναι μηδενική, και το μπαγιάτικο δεδομένα είναι ακόμα εκεί.


Τελικά, το μεταβίβασε το ακίνητο θα null έξω, αλλά αυτό ήταν μη-ντετερμινιστικό από την πλευρά μου.


Ο πυρήνας λόγος, όπως dbkk εννοεί είναι ότι η μητρική δοχείο ( `ObjA`με `PropB`) κρατά την περίπτωση `_PropB`στο πεδίο εφαρμογής, παρά το `Dispose()`.

 

Σε γενικές γραμμές, δεν χρειάζεται να ρυθμιστεί σε null. Αλλά ας υποθέσουμε ότι έχετε ένα Reset λειτουργικότητα στην τάξη σας.


Στη συνέχεια, μπορείτε να το κάνετε, γιατί δεν θέλετε να καλέσετε διαθέτει δύο φορές, δεδομένου ότι ορισμένες από τις Απορρίψτε δεν μπορεί να εφαρμοστεί σωστά και να ρίξει System.ObjectDisposed εξαίρεση.



```
private void Reset()
{
    if(_dataset != null)
    {
       _dataset.Dispose();
       _dataset = null;
    }
    //..More such member variables like oracle connection etc. _oraConnection
 }

```
 

Πιστεύω ότι με το σχεδιασμό των υλοποιητές GC, δεν μπορείτε να **επιταχύνει** GC με ακύρωση. Είμαι βέβαιος ότι θα ήθελα προτιμάτε να μην ανησυχείτε τον εαυτό σας με το πώς / πότε GC τρέχει - την αντιμετωπίσουμε σαν αυτό πανταχού παρούσα **Ον** προστασία και βλέποντας ξανά και για σας ... (σκύβει το κεφάλι προς τα κάτω, αυξάνει τη γροθιά προς τον ουρανό) .. .


Προσωπικά, έχω συχνά ορίζεται ρητά μεταβλητές με μηδενική όταν είμαι γίνει με αυτούς ως μια μορφή αυτο τεκμηρίωσης. Δεν δηλώνουν, χρησιμοποιούν, στη συνέχεια, ορίστε την σε κενή αργότερα - Ι null αμέσως μετά δεν είναι απαραίτητη. Λέω, ρητά, «είμαι επίσημα γίνει με σας ... να φύγει ...»


Είναι ακυρώνει αναγκαία σε μια γλώσσα GC'd; Όχι Είναι χρήσιμο για το GC; Ίσως ναι, ίσως όχι, δεν γνωρίζουμε με βεβαιότητα, από το σχεδιασμό πραγματικά δεν μπορώ να το ελέγξει, και ανεξάρτητα από τη σημερινή απάντηση με αυτή την έκδοση ή ότι, στο μέλλον εφαρμογές GC θα μπορούσε να αλλάξει την απάντηση πέρα από τον έλεγχό μου. Πλέον, αν / όταν μηδενισμού έχει βελτιστοποιηθεί έξω είναι λίγο περισσότερο από ένα φανταχτερό *σχόλιο* αν θέλετε. 


Μπορώ να καταλάβω αν κάνει η πρόθεσή μου σαφέστερη στην επόμενη φτωχούς ανόητος που ακολουθεί τα βήματά μου, και αν *«θα μπορούσε»* ενδεχομένως να βοηθήσει GC μερικές φορές, τότε αξίζει τον κόπο για μένα. Κυρίως αυτό με κάνει να αισθάνομαι τακτοποιημένο και καθαρό, και Mongo αρέσει να αισθάνονται τακτοποιημένο και καθαρό. :)


Θα το δει κανείς σαν αυτό: υπάρχουν γλώσσες προγραμματισμού για να αφήσουμε τους ανθρώπους να δώσουν άλλους ανθρώπους μια ιδέα προθέσεων και compiler αίτηση δουλειά του τι πρέπει να κάνουμε - ο compiler μετατρέπει το αίτημα αυτό σε μια διαφορετική γλώσσα (μερικές φορές αρκετές) για ένα CPU - η CPU (ες) θα μπορούσε να δώσει μια δεκάρα τι γλώσσα που χρησιμοποιείται, τις ρυθμίσεις σας καρτέλα, σχόλια, υφολογική έμφαση, τα ονόματα των μεταβλητών, κλπ - η CPU είναι όλα σχετικά με τη ροή bit που λέει ό, τι καταγράφει και κώδικες λειτουργίας και θέσεις μνήμης για να παίζω. Πολλά πράγματα γραμμένα σε κώδικα δεν μετατρέπονται σε αυτό που καταναλώνεται από την CPU με τη σειρά που έχει καθοριστεί. C μας, C ++, C #, Lisp, Βαβέλ, συναρμολόγησης ή οτιδήποτε άλλο είναι η θεωρία και όχι την πραγματικότητα, γράφεται ως μια δήλωση της εργασίας. Αυτό που βλέπετε δεν είναι αυτό που παίρνετε, ναι, ακόμη και σε γλώσσα μηχανής.


Καταλαβαίνω τη νοοτροπία του «περιττά πράγματα» (όπως κενές γραμμές) «δεν είναι παρά το θόρυβο και την ακαταστασία τον κώδικα.» Αυτό μου ήταν νωρίτερα στην καριέρα μου? Είμαι απόλυτα πάρει αυτό. Στο σημείο αυτό κλίνει προς αυτό το οποίο κάνει κωδικό σαφέστερη. Δεν είναι σαν να είμαι προσθέτοντας ακόμα 50 γραμμές «θόρυβο» στα προγράμματα μου - είναι μερικές γραμμές εδώ ή εκεί.


Υπάρχουν εξαιρέσεις σε κάθε κανόνα. Σε σενάρια με πτητική μνήμη, στατική μνήμη, συνθήκες του αγώνα, μονήρεις, η χρήση του «μπαγιάτικο» τα δεδομένα και όλα αυτού του είδους της σήψης, αυτό είναι διαφορετικό: Θα πρέπει να διαχειριστεί τη δική σας μνήμη, το κλείδωμα και ακυρώνει ως επίκαιρο, γιατί η μνήμη δεν είναι μέρος του η GC'd Σύμπαν - ελπίζω ο καθένας αντιλαμβάνεται ότι. Το υπόλοιπο του χρόνου με τις γλώσσες GC'd είναι θέμα στυλ και όχι ανάγκη ή μια εγγυημένη αύξηση της απόδοσης.


Στο τέλος της ημέρας, βεβαιωθείτε ότι έχετε κατανοήσει τι είναι επιλέξιμες για GC και τι όχι? κλειδαριά, απορρίψτε, και την εξουδετέρωση καταλλήλως? κερί για, κερί off? εισπνοή εκπνοή; και ό, τι άλλο μπορώ να πω: Αν αισθάνεται καλά, να το κάνει. απόσταση σε μίλια σας μπορεί να ποικίλει ... όπως θα έπρεπε ...

 