Προγραμματισμός

Μια βαθιά κατάδυση: Τύποι τιμών και αναφοράς στο .Net

Οι τύποι στο Microsoft .Net μπορεί να είναι είτε τύπος τιμής είτε τύπος αναφοράς. Ενώ οι τύποι τιμών αποθηκεύονται γενικά στη στοίβα, οι τύποι αναφοράς αποθηκεύονται στο σωρό διαχείρισης.

Ένας τύπος τιμής προέρχεται από το System.ValueType και περιέχει τα δεδομένα μέσα στη δική του κατανομή μνήμης. Με άλλα λόγια, οι μεταβλητές ή τα αντικείμενα ή οι τύποι τιμών έχουν το δικό τους αντίγραφο των δεδομένων.

Ένας τύπος αναφοράς, εν τω μεταξύ, επεκτείνει το System.Object και οδηγεί σε μια θέση στη μνήμη που περιέχει τα πραγματικά δεδομένα. Μπορείτε να φανταστείτε έναν τύπο αναφοράς παρόμοιο με έναν δείκτη που δεν αναφέρεται σιωπηρά όταν έχετε πρόσβαση σε αυτά. Οι ενσωματωμένοι τύποι αναφοράς που υποστηρίζονται από το C # περιλαμβάνουν: αντικείμενο, συμβολοσειρά και δυναμική. Όλοι οι βασικοί τύποι δεδομένων, Boolean, Ημερομηνία, δομές και αθροίσματα είναι παραδείγματα τύπων τιμών. Παραδείγματα τύπων αναφοράς περιλαμβάνουν: συμβολοσειρές, πίνακες, αντικείμενα τάξεων κ.λπ. Για να δημιουργήσετε τύπους αναφοράς στο C #, μπορείτε να επωφεληθείτε από αυτές τις λέξεις-κλειδιά: class, interface και delegate.

Σημειώστε ότι σε αντίθεση με έναν τύπο αναφοράς, δεν μπορείτε να προέλθετε από έναν τύπο τιμής, ούτε μπορείτε να εκχωρήσετε μια τιμή null απευθείας σε έναν τύπο τιμής. Μπορείτε να αντιστοιχίσετε μια τιμή null σε έναν τύπο τιμής μόνο εκμεταλλευόμενοι nullable τύπους - μια δυνατότητα που προστίθεται στις νεότερες εκδόσεις του .Net Framework. Όταν ένας τύπος τιμής αντιγράφεται σε έναν άλλο, η τιμή αντιγράφεται. Ως εκ τούτου, μπορείτε να χειριστείτε τις τιμές σε αυτές ανεξάρτητα από την άλλη - μια αλλαγή σε ένα δεν επηρεάζει την άλλη. Αντιθέτως, όταν αντιγράφετε έναν τύπο αναφοράς σε έναν άλλο, η αναφορά αντιγράφεται. Εάν αλλάξετε ένα από αυτά, το άλλο επηρεάζεται επίσης. Για παράδειγμα, εάν μία από τις αναφορές έχει οριστεί σε μηδέν, η άλλη γίνεται επίσης μηδενική.

Θέσεις αποθήκευσης

Το CLR αποθηκεύει αντικείμενα σε τρεις τύπους τοποθεσιών αποθήκευσης - τους καταχωρητές, τη στοίβα ή το σωρό που διαχειρίζεται. Ενώ τα βραχύβια αντικείμενα αποθηκεύονται σε καταχωρητές ή στοίβες, τα μακράς διαρκείας αντικείμενα αποθηκεύονται στο σωρό. Όπως ανέφερα νωρίτερα, οι τύποι τιμών συνήθως αποθηκεύονται στη στοίβα.

Είναι μια κοινή παρανόηση ότι οι τύποι τιμών αποθηκεύονται πάντα στη στοίβα. Θα προτιμούσα να πω ότι οι τύποι τιμών μπορώ να αποθηκευτεί στη στοίβα όταν η μεταβλητή είναι είτε προσωρινή μεταβλητή είτε τοπική μεταβλητή και ο μεταγλωττιστής JIT αποφασίζει να μην καταχωρίσει την τιμή. Στην ουσία, η πραγματική θέση ενός τύπου τιμής εξαρτάται από την εφαρμογή του μεταγλωττιστή JIT. Σημειώστε ότι ένας τύπος τιμής μπορεί να αποθηκευτεί σε ένα πλαίσιο στοίβας, στον καταχωρητή CPU ή ακόμα και στη μνήμη σωρού εάν ο τύπος τιμής περιέχεται μέσα σε ένα αντικείμενο, δηλ., Εάν είναι μέρος ενός τύπου αναφοράς. Αντίθετα, οι τύποι αναφοράς αποθηκεύονται στο σωρό GC. Η αναφορά αποθηκεύεται σε μια στοίβα ενώ το αντικείμενο κατανέμεται στο σωρό.

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

Περνώντας από την τιμή και περνώντας με αναφορά

Η ακόλουθη λίστα κωδικών δείχνει πώς μπορείτε να μεταβιβάσετε μια μεταβλητή σε μια μέθοδο με αξία.

 αύξηση στατικού κενού (int i)

        {

i = i + 1;

        }

στατικό κενό Κεντρικό ()

        {

int x = 1;

Αύξηση (x);

Console.WriteLine ("Η τιμή του x είναι:" + x);

Κονσόλα. Διαβάστε ();

        }

Σημειώστε ότι μπορείτε να μεταβιβάσετε έναν τύπο τιμής ως αναφορά σε μια μέθοδο χρησιμοποιώντας τη λέξη-κλειδί ref. Η ακόλουθη λίστα κωδικών το δείχνει αυτό.

αύξηση στατικού κενού (ref int i)

        {

i = i + 1;

        }

στατικό κενό Κεντρικό ()

        {

int x = 1;

Αύξηση (ref x);

Console.WriteLine ("Η τιμή του x είναι:" + x);

Κονσόλα. Διαβάστε ();

        }

Όταν εκτελείται ο παραπάνω κωδικός, το μήνυμα "Η τιμή του x είναι: 2" θα εμφανιστεί στην κονσόλα.

Πυγμαχία και απεμπλοκή

Η μετατροπή ενός τύπου τιμής σε έναν τύπο αναφοράς είναι γνωστή ως πυγμαχία. Το Unboxing είναι ακριβώς το αντίθετο - ορίζεται ως η διαδικασία μετατροπής ενός τύπου αναφοράς σε έναν τύπο τιμής. Το ακόλουθο απόσπασμα κώδικα απεικονίζει την πυγμαχία και την αποσυμπίεση στο C #.

int i = 100;

Αντικείμενο obj = i; //Πυγμαχία

i = (int) obj; // Αποσύνδεση