Bagikan melalui


17 Array

17.1 Umum

Array adalah struktur data yang berisi sejumlah variabel yang diakses melalui indeks yang dihitung. Variabel yang terkandung dalam array, juga disebut elemen array, semuanya dari jenis yang sama, dan jenis ini disebut jenis elemen array.

Array memiliki peringkat yang menentukan jumlah indeks yang terkait dengan setiap elemen array. Peringkat array juga disebut sebagai dimensi array. Array dengan peringkat satu disebut array dimensi tunggal. Array dengan peringkat yang lebih besar dari satu disebut array multi-dimensi. Array multi-dimensi berukuran tertentu sering disebut sebagai array dua dimensi, array tiga dimensi, dan sebagainya. Setiap dimensi array memiliki panjang terkait yang merupakan angka integral yang lebih besar dari atau sama dengan nol. Panjang dimensi bukan bagian dari jenis array, melainkan dibuat ketika instans jenis array dibuat pada run-time. Panjang dimensi menentukan rentang indeks yang valid untuk dimensi tersebut: Untuk dimensi panjang N, indeks dapat berkisar dari 0 hingga N – 1 inklusif. Jumlah total elemen dalam array adalah produk dari panjang setiap dimensi dalam array. Jika satu atau beberapa dimensi array memiliki panjang nol, array dikatakan kosong.

Jenis elemen array itu sendiri dapat berupa jenis array (§17.2.1). Array array semacam itu berbeda dari array multi-dimensi dan dapat digunakan untuk mewakili "larik jagged".

Contoh:

int[][] pascals = 
{
    new int[] {1},
    new int[] {1, 1},
    new int[] {1, 2, 1},
    new int[] {1, 3, 3, 1}
};

contoh akhir

Setiap jenis array adalah jenis referensi (§8.2). Jenis elemen array dapat berupa jenis apa pun, termasuk jenis nilai dan jenis array.

17.2 Jenis array

17.2.1 Umum

Produksi tata bahasa untuk jenis array disediakan dalam §8.2.1.

Jenis array ditulis sebagai non_array_type diikuti oleh satu atau beberapa rank_specifier.

Non_array_type adalah jenis apa pun yang bukan merupakan array_type.

Peringkat jenis array diberikan oleh rank_specifier paling kiri dalam array_type: rank_specifier menunjukkan bahwa array adalah array dengan peringkat satu ditambah jumlah token "," dalam rank_specifier.

Jenis elemen dari jenis array adalah jenis yang dihasilkan dari menghapus rank_specifier paling kiri:

  • Jenis array formulir T[R] adalah array dengan peringkat R dan jenis Telemen non-array .
  • Jenis array formulir T[R][R₁]...[Rₓ] adalah array dengan peringkat R dan jenis T[R₁]...[Rₓ]elemen .

Akibatnya , rank_specifierdibaca dari kiri ke kanan sebelum jenis elemen non-array akhir.

Contoh: Jenis di T[][,,][,] adalah array dimensi tunggal dari array tiga dimensi dari array dua dimensi .int contoh akhir

Pada run-time, nilai jenis array bisa atau null referensi ke instans jenis array tersebut.

Catatan: Mengikuti aturan §17.6, nilainya mungkin juga merupakan referensi ke jenis array kovarian. catatan akhir

17.2.2 Jenis System.Array

Jenisnya System.Array adalah jenis dasar abstrak dari semua jenis array. Konversi referensi implisit (§10.2.8) ada dari jenis array apa pun ke System.Array dan ke jenis antarmuka apa pun yang diimplementasikan oleh System.Array. Konversi referensi eksplisit (§10.3.5) ada dari System.Array dan jenis antarmuka apa pun yang diimplementasikan oleh System.Array ke jenis array apa pun. System.Arraybukan array_type. Sebaliknya, itu adalah class_type dari mana semua array_typediturunkan.

Pada run-time, nilai jenis System.Array dapat berupa null atau referensi ke instans jenis array apa pun.

17.2.3 Array dan antarmuka koleksi generik

Array T[] dimensi tunggal mengimplementasikan antarmuka System.Collections.Generic.IList<T> (IList<T> singkatnya) dan antarmuka dasarnya. Oleh karena itu, ada konversi implisit dari T[] ke IList<T> dan antarmuka dasarnya. Selain itu, jika ada konversi referensi implisit dari ke kemudian mengimplementasikan dan ada konversi referensi implisit IList<T> dari S[] ke IList<T> dan antarmuka dasarnya (§10.2.8).S[] T S Jika ada konversi referensi eksplisit dari S ke T maka ada konversi referensi eksplisit dari S[] ke IList<T> dan antarmuka dasarnya (§10.3.5).

Demikian pula, array T[] dimensi tunggal juga mengimplementasikan antarmuka System.Collections.Generic.IReadOnlyList<T> (IReadOnlyList<T> singkatnya) dan antarmuka dasarnya. Oleh karena itu, ada konversi implisit dari T[] ke IReadOnlyList<T> dan antarmuka dasarnya. Selain itu, jika ada konversi referensi implisit dari ke kemudian mengimplementasikan dan ada konversi referensi implisit IReadOnlyList<T> dari S[] ke IReadOnlyList<T> dan antarmuka dasarnya (§10.2.8).S[] T S Jika ada konversi referensi eksplisit dari S ke T maka ada konversi referensi eksplisit dari S[] ke IReadOnlyList<T> dan antarmuka dasarnya (§10.3.5).

Contoh: Misalnya:

class Test
{
    static void Main()
    {
        string[] sa = new string[5];
        object[] oa1 = new object[5];
        object[] oa2 = sa;

        IList<string> lst1 = sa;  // Ok
        IList<string> lst2 = oa1; // Error, cast needed
        IList<object> lst3 = sa;  // Ok
        IList<object> lst4 = oa1; // Ok

        IList<string> lst5 = (IList<string>)oa1; // Exception
        IList<string> lst6 = (IList<string>)oa2; // Ok

        IReadOnlyList<string> lst7 = sa;        // Ok
        IReadOnlyList<string> lst8 = oa1;       // Error, cast needed
        IReadOnlyList<object> lst9 = sa;        // Ok
        IReadOnlyList<object> lst10 = oa1;      // Ok
        IReadOnlyList<string> lst11 = (IReadOnlyList<string>)oa1; // Exception
        IReadOnlyList<string> lst12 = (IReadOnlyList<string>)oa2; // Ok
    }
}

Penugasan lst2 = oa1 menghasilkan kesalahan waktu kompilasi karena konversi dari object[] ke IList<string> adalah konversi eksplisit, bukan implisit. Pemeran (IList<string>)oa1 akan menyebabkan pengecualian dilemparkan pada run-time karena oa1 mereferensikan dan object[] bukan string[]. Namun pemeran (IList<string>)oa2 tidak akan menyebabkan pengecualian dilemparkan karena oa2 mereferensikan string[].

contoh akhir

Setiap kali ada konversi referensi implisit atau eksplisit dari S[] ke IList<T>, ada juga konversi referensi eksplisit dari IList<T> dan antarmuka dasarnya ke S[] (§10.3.5).

Ketika jenis S[] array mengimplementasikan IList<T>, beberapa anggota antarmuka yang diimplementasikan dapat melemparkan pengecualian. Perilaku yang tepat dari implementasi antarmuka berada di luar cakupan spesifikasi ini.

17.3 Pembuatan array

Instans array dibuat oleh array_creation_expression (§12.8.16.5) atau berdasarkan deklarasi variabel bidang atau lokal yang menyertakan array_initializer (§17,7). Instans array juga dapat dibuat secara implisit sebagai bagian dari mengevaluasi daftar argumen yang melibatkan array parameter (§15.6.2.4).

Saat instans array dibuat, peringkat dan panjang setiap dimensi dibuat dan kemudian tetap konstan selama seluruh masa pakai instans. Dengan kata lain, tidak dimungkinkan untuk mengubah peringkat instans array yang ada, juga tidak mungkin untuk mengubah ukuran dimensinya.

Instans array selalu dari jenis array. Jenisnya System.Array adalah jenis abstrak yang tidak dapat diinstansiasi.

Elemen array yang dibuat oleh array_creation_expressionselalu diinisialisasi ke nilai defaultnya (§9,3).

17.4 Akses elemen Array

Elemen array diakses menggunakan ekspresi element_access (§12.8.11.2) formulir A[I₁, I₂, ..., Iₓ], di mana A adalah ekspresi jenis array dan masing-masing Iₑ adalah ekspresi jenis int, , uint, long, ulongatau dapat dikonversi secara implisit ke satu atau beberapa jenis ini. Hasil dari akses elemen array adalah variabel, yaitu elemen array yang dipilih oleh indeks.

Elemen array dapat dijumlahkan menggunakan foreach pernyataan (§13.9.5).

17.5 Anggota array

Setiap jenis array mewarisi anggota yang dideklarasikan oleh jenis .System.Array

17.6 Kovarian array

Untuk dua reference_type dan A , jika konversi referensi implisit (§10.2.8) atau konversi referensi eksplisit (§10.3.5) ada dari A ke B, maka konversi referensi yang sama juga ada dari jenis array ke jenis B[R]A[R] array , di mana R ada rank_specifier yang diberikan (tetapi sama untuk kedua jenis array).B Hubungan ini dikenal sebagai kovarians array. Kovarians array, khususnya, berarti bahwa nilai jenis A[R] array mungkin benar-benar menjadi referensi ke instans jenis B[R]array , asalkan konversi referensi implisit ada dari B ke A.

Karena kovarians array, penugasan ke elemen array jenis referensi menyertakan pemeriksaan run-time yang memastikan bahwa nilai yang ditetapkan ke elemen array sebenarnya dari jenis yang diizinkan (§12.21.2).

Contoh:

class Test
{
    static void Fill(object[] array, int index, int count, object value) 
    {
        for (int i = index; i < index + count; i++)
        {
            array[i] = value;
        }
    }

    static void Main() 
    {
        string[] strings = new string[100];
        Fill(strings, 0, 100, "Undefined");
        Fill(strings, 0, 10, null);
        Fill(strings, 90, 10, 0);
    }
}

Penugasan ke array[i] dalam Fill metode secara implisit menyertakan pemeriksaan run-time, yang memastikan bahwa value itu adalah null referensi atau referensi ke objek jenis yang kompatibel dengan jenis elemen aktual .array Dalam Main, dua pemanggilan Fill pertama berhasil, tetapi pemanggilan ketiga menyebabkan System.ArrayTypeMismatchException dilemparkan saat menjalankan tugas pertama ke array[i]. Pengecualian terjadi karena kotak int tidak dapat disimpan dalam string array.

contoh akhir

Kovarian array secara khusus tidak meluas ke array value_types. Misalnya, tidak ada konversi yang mengizinkan untuk int[] diperlakukan sebagai object[].

17.7 Penginisialisasi array

Penginisialisasi array dapat ditentukan dalam deklarasi bidang (§15,5), deklarasi variabel lokal (§13.6.2), dan ekspresi pembuatan array (§12.8.16.5):

array_initializer
    : '{' variable_initializer_list? '}'
    | '{' variable_initializer_list ',' '}'
    ;

variable_initializer_list
    : variable_initializer (',' variable_initializer)*
    ;
    
variable_initializer
    : expression
    | array_initializer
    ;

Penginisialisasi array terdiri dari urutan penginisialisasi variabel, diapit oleh token "{" dan "}" dan dipisahkan oleh token "",. Setiap penginisialisasi variabel adalah ekspresi atau, dalam kasus array multi-dimensi, penginisialisasi array berlapis.

Konteks di mana penginisialisasi array digunakan menentukan jenis array yang sedang diinisialisasi. Dalam ekspresi pembuatan array, jenis array segera mendahului penginisialisasi, atau disimpulkan dari ekspresi dalam penginisialisasi array. Dalam deklarasi bidang atau variabel, jenis array adalah jenis bidang atau variabel yang dideklarasikan. Saat penginisialisasi array digunakan dalam deklarasi bidang atau variabel,

int[] a = {0, 2, 4, 6, 8};

ini hanya singkatan untuk ekspresi pembuatan array yang setara:

int[] a = new int[] {0, 2, 4, 6, 8};

Untuk array dimensi tunggal, penginisialisasi array harus terdiri dari urutan ekspresi, masing-masing memiliki konversi implisit ke jenis elemen array (§10,2). Ekspresi menginisialisasi elemen array dalam urutan yang meningkat, dimulai dengan elemen pada nol indeks. Jumlah ekspresi dalam penginisialisasi array menentukan panjang instans array yang dibuat.

Contoh: Penginisialisasi array di atas membuat instans int[] panjang 5 lalu menginisialisasi instans dengan nilai berikut:

a[0] = 0; a[1] = 2; a[2] = 4; a[3] = 6; a[4] = 8;

contoh akhir

Untuk array multi-dimensi, penginisialisasi array harus memiliki tingkat bersarang sebanyak ada dimensi dalam array. Tingkat berlapis terluar sesuai dengan dimensi paling kiri dan tingkat berlapis terdahulu sesuai dengan dimensi paling kanan. Panjang setiap dimensi array ditentukan oleh jumlah elemen pada tingkat berlapis yang sesuai dalam penginisialisasi array. Untuk setiap penginisialisasi array berlapis, jumlah elemen harus sama dengan penginisialisasi array lainnya pada tingkat yang sama.

Contoh: Contoh:

int[,] b = {{0, 1}, {2, 3}, {4, 5}, {6, 7}, {8, 9}};

membuat array dua dimensi dengan panjang lima untuk dimensi paling kiri dan panjang dua untuk dimensi paling kanan:

int[,] b = new int[5, 2];

lalu menginisialisasi instans array dengan nilai berikut:

b[0, 0] = 0; b[0, 1] = 1;
b[1, 0] = 2; b[1, 1] = 3;
b[2, 0] = 4; b[2, 1] = 5;
b[3, 0] = 6; b[3, 1] = 7;
b[4, 0] = 8; b[4, 1] = 9;

contoh akhir

Jika dimensi selain yang paling kanan diberikan dengan panjang nol, dimensi berikutnya diasumsikan juga memiliki panjang nol.

Contoh:

int[,] c = {};

membuat array dua dimensi dengan panjang nol untuk dimensi paling kiri dan paling kanan:

int[,] c = new int[0, 0];

contoh akhir

Ketika ekspresi pembuatan array mencakup panjang dimensi eksplisit dan penginisialisasi array, panjangnya harus berupa ekspresi konstan dan jumlah elemen di setiap tingkat berlapis harus cocok dengan panjang dimensi yang sesuai.

Contoh: Berikut adalah beberapa contoh:

int i = 3;
int[] x = new int[3] {0, 1, 2}; // OK
int[] y = new int[i] {0, 1, 2}; // Error, i not a constant
int[] z = new int[3] {0, 1, 2, 3}; // Error, length/initializer mismatch

Di sini, penginisialisasi untuk y menghasilkan kesalahan waktu kompilasi karena ekspresi panjang dimensi bukan konstanta, dan inisialisasi untuk z menghasilkan kesalahan waktu kompilasi karena panjang dan jumlah elemen dalam penginisialisasi tidak setuju.

contoh akhir

Catatan: C# memungkinkan koma berikutnya di akhir array_initializer. Sintaks ini memberikan fleksibilitas dalam menambahkan atau menghapus anggota dari daftar tersebut, dan menyederhanakan pembuatan mesin daftar tersebut. catatan akhir