Penyelaman mendalam: Nilai dan jenis rujukan di .Net

Jenis di Microsoft .Net boleh berupa jenis nilai atau jenis rujukan. Walaupun jenis nilai biasanya disimpan dalam timbunan, jenis rujukan disimpan di timbunan terurus.

Jenis nilai berasal dari System.ValueType dan mengandungi data di dalam peruntukan memori sendiri. Dengan kata lain, pemboleh ubah atau objek atau jenis nilai mempunyai salinan data mereka sendiri.

Jenis rujukan, sementara itu, meluaskan System.Object dan menunjuk ke lokasi dalam memori yang mengandungi data sebenar. Anda boleh membayangkan jenis rujukan yang serupa dengan penunjuk yang secara tidak langsung tidak dapat diturunkan semasa anda mengaksesnya. Jenis rujukan terbina dalam yang disokong oleh C # merangkumi: objek, rentetan, dan dinamik. Semua jenis data asas, Boolean, Tarikh, struktur, dan enum adalah contoh jenis nilai. Contoh jenis rujukan termasuk: rentetan, tatasusunan, objek kelas, dll. Untuk membuat jenis rujukan di C #, anda boleh memanfaatkan kata kunci ini: kelas, antara muka dan perwakilan.

Perhatikan bahawa tidak seperti jenis rujukan, anda tidak boleh memperoleh dari jenis nilai, dan anda juga tidak boleh memberikan nilai nol langsung ke jenis nilai. Anda boleh menetapkan nilai nol untuk jenis nilai hanya dengan memanfaatkan jenis yang tidak dapat ditolak - satu ciri yang ditambahkan ke versi .Net Framework yang lebih baru. Apabila jenis nilai disalin ke yang lain, nilainya disalin. Oleh itu, anda boleh memanipulasi nilai-nilai di dalamnya bebas dari yang lain - perubahan pada satu tidak mempengaruhi yang lain. Sebaliknya, apabila anda menyalin jenis rujukan ke yang lain, rujukan disalin. Sekiranya anda menukar salah satu daripadanya, yang lain juga akan terjejas. Sebagai contoh, jika salah satu rujukan ditetapkan ke nol, yang lain juga menjadi batal.

Lokasi simpanan

CLR menyimpan objek di tiga jenis lokasi penyimpanan - daftar, timbunan atau timbunan terurus. Walaupun objek berumur pendek disimpan di dalam daftar atau timbunan, objek yang berumur panjang disimpan di timbunan. Seperti yang saya nyatakan sebelumnya, jenis nilai umumnya disimpan dalam timbunan.

Kesalahpahaman umum bahawa jenis nilai selalu disimpan dalam timbunan. Saya lebih suka mengatakan bahawa jenis nilai yang boleh disimpan dalam tindanan apabila pembolehubah sama ada pembolehubah sementara atau adalah pembolehubah tempatan dan pengkompil JIT memutuskan untuk tidak enregister nilai. Pada hakikatnya, lokasi sebenar jenis nilai bergantung pada pelaksanaan penyusun JIT. Perhatikan bahawa jenis nilai dapat disimpan dalam bingkai tumpukan, dalam daftar CPU atau bahkan di memori timbunan jika jenis nilai terkandung di dalam objek, yaitu, jika itu adalah bagian dari jenis rujukan. Sebaliknya, jenis rujukan disimpan di timbunan GC. Rujukan disimpan dalam timbunan sementara objek diperuntukkan di timbunan.

Contoh atau rujukan dari jenis nilai disimpan di timbunan, daftar atau di timbunan bergantung pada sama ada masa hidup contoh atau rujukan itu berumur pendek atau lama. Jenis nilai boleh berada di timbunan jika mereka adalah pemboleh ubah tempatan dan di timbunan terurus jika mereka adalah bidang kelas, iaitu, ia termasuk atau merupakan bahagian dari jenis rujukan.

Lulus dengan nilai dan lulus dengan merujuk

Penyenaraian kod berikut menggambarkan bagaimana anda boleh meneruskan pemboleh ubah ke kaedah mengikut nilai.

 static void Increment(int i)

        {

            i = i + 1;

        }

        static void Main()

        {

            int x = 1;

            Increment(x);

            Console.WriteLine("The value of x is: " +x);

            Console.Read();

        }

Perhatikan bahawa anda boleh memberikan jenis nilai sebagai rujukan kepada kaedah dengan menggunakan kata kunci ref. Penyenaraian kod berikut menggambarkan ini.

static void Increment(ref int i)

        {

            i = i + 1;

        }

        static void Main()

        {

            int x = 1;

            Increment(ref x);

            Console.WriteLine("The value of x is: " +x);

            Console.Read();

        }

Apabila kod di atas dijalankan, mesej "Nilai x adalah: 2" akan dipaparkan di konsol.

Tinju dan unboxing

Penukaran jenis nilai menjadi jenis rujukan dikenali sebagai tinju. Membuka kotak adalah sebaliknya - ia ditakrifkan sebagai proses penukaran jenis rujukan ke jenis nilai. Coretan kod berikut menggambarkan tinju dan unboxing di C #.

int i = 100;

Object obj = i; //Boxing

i = (int) obj; //Unboxing