Apakah int [] merupakan tipe referensi atau tipe nilai?

124

Saya tahu int adalah tipe nilai, tetapi apa itu array tipe nilai? Jenis referensi? Jenis nilai? Saya ingin meneruskan array ke fungsi untuk memeriksa sesuatu. Haruskah saya meneruskan array, karena itu hanya akan meneruskan referensi itu, atau haruskah saya meneruskannya sebagai ref?

melahap elysium
sumber
11
Di masa mendatang, Anda dapat memeriksa apakah ada sesuatu yang diteruskan oleh referensi atau nilai dengan membuat variabel, meneruskan variabel tersebut ke dalam metode yang mengubah variabel tersebut, dan memeriksa berapa nilai variabel tersebut setelah dijalankan melalui metode. Jika sama, nilai yang diteruskan, berbeda, diteruskan oleh referensi.
11
@ darkassassin93: Meneruskan dengan referensi atau dengan nilai tidak terkait dengan apakah sesuatu adalah tipe referensi atau tipe nilai. (Jenis nilai dapat dilalui dengan referensi dan jenis referensi dapat diteruskan dengan nilai.)
LukeH
2
Dalam kebanyakan kasus, jika Anda dapat menyimpan [null] di dalam kolom atau variabel, Anda dapat mengasumsikan bahwa itu adalah tipe ref. Pengecualiannya tentu adalah tipe nullable (Nullable <int> atau int?) Serta string.
Noel Widmer
3
@ NoëlWidmer String bukan merupakan pengecualian: mereka adalah tipe referensi.
Arthur Castro
2
@ArthurCastro Argree to 50%: string mewarisi dari kelas yang berarti mereka adalah tipe referensi. Namun kesetaraan mereka didasarkan pada identitas (perbandingan nilai) daripada referensi dan perilaku lulus mereka diganti untuk mencocokkan perilaku tipe nilai. Pada dasarnya mereka adalah tipe referensi menurut definisi tetapi berperilaku lebih seperti tipe nilai melalui implementasi.
Noel Widmer

Jawaban:

201

Array adalah mekanisme yang memungkinkan Anda memperlakukan beberapa item sebagai satu koleksi. Microsoft® .NET Common Language Runtime (CLR) mendukung array satu dimensi, array multidimensi, dan array bergerigi (array array). Semua tipe array secara implisit diturunkan dari System.Array, yang diturunkan dari System.Object. Artinya, semua larik selalu merupakan tipe referensi yang dialokasikan pada heap terkelola, dan variabel aplikasi Anda berisi referensi ke larik dan bukan ke larik itu sendiri.

https://msdn.microsoft.com/en-us/library/bb985948.aspx

Yannick Motton
sumber
54
Jenis nilai mewarisi dari System.ValueType yang mewarisi sendiri dari System.Object. Jadi hanya karena Array berasal dari System.Object tidak berarti itu adalah tipe referensi. Apa yang membuat System.Array menjadi tipe referensi adalah bahwa instansinya disalin dengan referensi. IOW, berkonsentrasilah pada fakta bahwa System.Array adalah sebuah kelas. Itulah yang membuatnya menjadi tipe referensi.
P. Brian.Meyey
8
<nitpick> Saya tahu sepertinya dokumentasinya menyiratkan bahwa System.Array yang diturunkan dari System.Object menjadikannya sebagai tipe referensi. Meskipun mungkin tidak benar bahwa semua tipe yang diturunkan dari System.Object adalah tipe referensi, satu-satunya pengecualian untuk aturan ini adalah System.ValueType, yang diperlakukan berbeda oleh kompilator. </nitpick>
Yannick Motton
Tautan di atas rusak. Berikut ini adalah tautan msdn lain yang menunjukkan hierarki pewarisan
System. Array
Apa pun yang berasal dari System.Object adalah tipe referensi, KECUALI juga berasal dari System.ValueType. @ P.Brian.Mackey hanya karena suatu tipe adalah kelas tidak berarti itu adalah tipe referensi, karena di belakang layar, struct hanyalah kelas yang diturunkan dari System.ValueType.
David Klempfner
31

Tes paling sederhana untuk tipe referensi vs. tipe nilai adalah tipe referensi bisa null, tapi tipe nilai tidak bisa.

Alex Reitbort
sumber
46
... kecuali untuk tipe nilai nullable, yang nullable (Anda dapat menyetel nilainya menjadi null, yang berarti nilai null untuk jenis tersebut, bukan referensi null ) dan masih merupakan tipe nilai.
Jon Skeet
1
Jangan pernah berpikir untuk melakukan itu ketika mencoba memahami apakah mereka tipe nilai atau bukan! Ide yang hebat.
melahap elysium
6

Pertama saya ingin memberi tahu Anda bahwa Array adalah tipe referensi. Mengapa? Saya menjelaskan melempar satu contoh di sini.

Contoh:

int val = 0; // this is a value type ok
int[] val1 = new int[20] // this is a reference type because space required to store 20 integer value that make array allocated on the heap.

Juga tipe referensi bisa nol sedangkan tipe nilai tidak bisa.

tipe nilai yang disimpan di Stack dan tipe referensi yang disimpan di Heap

Anda dapat mengirimkan array ke fungsi menggunakan out atau ref. Hanya metode inisialisasi yang berbeda.

lebih..

Devendra Gohel
sumber
3

Uji untuk memverifikasi apakah itu referensi atau tipe nilai:

// we create a simple array of int
var a1 = new int[]{1,2,3};
// copy the array a1 to a2
var a2 = a1;
// modify the first element of a1
a1[0]=2;
// output the first element of a1 and a2
Console.WriteLine("a1:"+a1[0]); // 2
Console.WriteLine("a2:"+a2[0]); // 2
//**************************
// all the two variable point to the same array
// it's reference type!
//**************************

Anda dapat mengujinya secara online: https://dotnetfiddle.net/UWFP45

Marco Staffoli
sumber
2
Akan lebih mudah untuk membuat sebuah array dan mencoba untuk menugaskannya ke null. Kompilasi akan gagal jika itu adalah tipe nilai ..
melahap elysium
Lebih dulu. Setelah C # 8 dilepaskan, itu juga akan gagal jika Anda menggunakan fitur tipe referensi nullable karena tipe referensi non-nullable juga tidak dapat menerima null.
Mark A. Donohoe
2

Array itu sendiri adalah tipe referensi. Nilai dari array itu adalah tipe nilai atau referensi seperti yang ditentukan oleh tipe data array. Dalam contoh Anda, array adalah tipe referensi dan nilainya adalah tipe nilai.

Semua larik berdimensi tunggal diimplementasikan secara implisit IList<T>, di mana <T>tipe datanya adalah larik. Anda dapat menggunakan antarmuka tersebut sebagai tipe data dari parameter metode Anda. Anda juga bisa menggunakan IEnumerable<T>untuk tipe data. Dalam kedua kasus (atau bahkan jika Anda hanya menggunakan int[]) Anda tidak perlu meneruskannya secara eksplisit sebagai refparameter.

Scott Dorman
sumber
0

// Referensi ke array diteruskan oleh nilai. Ini adalah sumber kebingungan :-) ...

        int[] test = { 1, 2, 3, 4 };

        modifContenuSansRef(test);
        Console.WriteLine(test[0]); // OK --> 99 le contenu du tableau est modifié

        modifTailleSansRef(test);
        Console.WriteLine(test.Length); // KO --> 4 La taille n'est pas modifiée

    }

    static void modifContenuSansRef(int[] t)
    {
        t[0] = 99;
    }

    static void modifTailleSansRef(int[] t)
    {
        Array.Resize(ref t, 8);
    }
Domi
sumber
0

Array selalu merupakan tipe referensi. Tidak masalah array akan berisi tipe nilai seperti int atau tipe referensi seperti string. Saat Anda mendeklarasikan array misalnya

int[] integers=new int[10];

Variabel integers itu sendiri hanya berisi referensi ke array yang akan ditempatkan di heap.

Juga ada banyak orang yang menyebutkan bahwa Anda dapat membedakan tipe nilai dari tipe referensi hanya bergantung pada fakta bahwa variabel itu bisa nol atau tidak. Saya ingin menyebutkan bahwa dalam c # jenis nilai saat ini juga bisa menjadi null

misalnya

int? integer=null

dan itu bukan cara yang baik untuk mengidentifikasi jenisnya adalah referensi atau nilai hanya bergantung pada variabel fakta bisa menjadi nol atau tidak.

So_oP
sumber
-2

Sedikit wawasan:

Misalnya, intmewakili satu bilangan bulat, int[]mewakili larik bilangan bulat.

Untuk menginisialisasi array dengan dimensi tertentu, Anda dapat menggunakan newkata kunci, memberikan ukuran dalam tanda kurung siku setelah nama jenis:

//create a new array of 32 ints.
int[] integers = new int[32];

Semua array adalah tipe referensi dan mengikuti semantik referensi. Karenanya, dalam kode ini, meskipun elemen individual adalah tipe nilai primitif, integersarray adalah tipe referensi. Jadi jika nanti Anda menulis:

int[] copy = integers;

ini hanya akan menetapkan seluruh salinan variabel untuk merujuk ke array yang sama, itu tidak akan membuat array baru.

Sintaks array C # bersifat fleksibel, ini memungkinkan Anda untuk mendeklarasikan array tanpa menginisialisasi mereka sehingga array tersebut dapat diukur secara dinamis nanti dalam program. Dengan teknik ini, pada dasarnya Anda membuat referensi null dan kemudian mengarahkan referensi tersebut ke bentangan lokasi memori yang dialokasikan secara dinamis yang diminta dengan newkata kunci:

int[] integers;
integers = new int[32];

Terima kasih.

Rahul Bhat
sumber