Bagaimana cara menginisialisasi array kosong di C #?

Jawaban:

435

Jika Anda akan menggunakan koleksi yang sebelumnya tidak Anda ketahui ukurannya, ada opsi yang lebih baik daripada array.

Gunakan List<string>sebaliknya - itu akan memungkinkan Anda untuk menambahkan item sebanyak yang Anda butuhkan dan jika Anda perlu mengembalikan array, panggil ToArray()variabel tersebut.

var listOfStrings = new List<string>();

// do stuff...

string[] arrayOfStrings = listOfStrings.ToArray();

Jika Anda harus membuat array kosong, Anda dapat melakukan ini:

string[] emptyStringArray = new string[0]; 
Oded
sumber
1
@Oded - string [] emptyStringArray = string baru [0]; tidak menghasilkan array kosong, bukan? Sepertinya itu array dengan satu elemen di mana elemen itu nol.
rory.ap
11
@roryap - Tidak. Ini menghasilkan string[]yang tidak memiliki elemen. Jika Anda mencoba mengakses emptyStringArray[0], Anda akan mendapatkanIndexOutOfRangeException
Oded
@Oded - Terima kasih, saya cukup baru di C #. Dalam VB, indeks yang diberikan adalah batas atas, bukan jumlah elemen.
rory.ap
1
Apa yang akan Anda pertimbangkan lebih baik: var strings = new string [] {}; atau var string = string baru [0]; BTW: Saya menganggap sebuah array kosong sebagai standar yang valid untuk parameter metode: public void EditItems (IEnumerable <Item> toEdit, IEnumerable <long> toDelete = new long [] {})
realbart
6
@ RickO'Shea - C ++ bukan C #. Stroustrup tahu C ++ -nya - tidak begitu yakin dia tahu C # dan .NET GC. Tidak akan berperang agama denganmu.
Oded
181

Coba ini:

string[] a = new string[] { };
hemant
sumber
7
Memperluas jawaban ini, Anda juga dapat init array dengan item tanpa menentukan ukuran ATAU jenis, kompiler akan menyimpulkan baik dari penginisialisasi: var a = new [] {"a", "b", "c"}; Ini masih berupa array string yang sangat diketik.
Nick VanderPyle
1
Pengecualian Tidak Tertangani: System.IndexOutOfRangeException: Indeks berada di luar boun ds array. di ArrayClass.Main (String [] args). Saya menghadapi kesalahan ini setelah saya mengubah variabel int [] = new int [] {}
yogesh
6
@Yogesh: Itu aneh. Ketika misalnya menulis int[] variable = new int[]{}dan menggunakannya misalnya dalam satu lingkaran seperti foreach (var s in variable){ Console.WriteLine(s);}kode dikompilasi ke: int[] args1 = new int[0];dan foreach (int num in args1){Console.WriteLine(num);}. Jadi seharusnya tidak ada perbedaan antara menggunakan new int[0]dan new int[]{}karena keduanya dikompilasi ke kode yang sama.
Tidak
1
@GlennGordon Tentu saja, tapi itu baru pada C # versi 3.0 (dari 2007, dengan Visual Studio 2008). Versi itu juga memungkinkan format sederhana lain dengan var, meskipun hanya untuk variabel lokal (bukan untuk bidang). Namun dalam C # 2.0 (Visual Studio 2005) dan sebelumnya, Anda harus menggunakan sintaks dari jawaban ini (atau string[] a = new string[0];).
Jeppe Stig Nielsen
113

NET 4.6 cara disukai adalah dengan menggunakan metode baru, Array.Empty:

String[] a = Array.Empty<string>();

The implementasi adalah ringkas, menggunakan bagaimana anggota statis di kelas generik berperilaku Net :

public static T[] Empty<T>()
{
    return EmptyArray<T>.Value;
}

// Useful in number of places that return an empty byte array to avoid
// unnecessary memory allocation.
internal static class EmptyArray<T>
{
    public static readonly T[] Value = new T[0];
}

(kode kontrak terkait kode dihapus untuk kejelasan)

Lihat juga:

Kobi
sumber
@Cole Johnson - Terima kasih atas hasil editnya, tapi saya gulung balik. Saya sengaja menghilangkan baris-baris ini: Saya hanya ingin mengutip implementasi yang menarik. Kontrak kode dan atribut hanya menghalangi cara memahami apa yang terjadi (tautan ke sumber memiliki segalanya, tentu saja). Saya juga menambahkan baris baru di komentar untuk menghindari bergulir di Stack Overflow. Jika Anda tidak keberatan, saya lebih suka seperti ini. Terima kasih!
Kobi
2
Jelas merupakan peningkatan untuk keterbacaan dari:Enumerable.Empty<T>().ToArray()
DanielV
Meskipun metode ini lebih disukai dalam banyak kasus, metode ini tidak menjawab pertanyaan awal. OP ingin membuat array kosong. Array.Empty<T>()tidak tidak membuat sebuah array. Ini mengembalikan referensi ke array yang dialokasikan sebelumnya.
l33t
33

Anda bisa menginisialisasi dengan ukuran 0, tetapi Anda harus menginisialisasi ulang, ketika Anda tahu apa ukurannya, karena Anda tidak dapat menambahkan ke array.

string[] a = new string[0];
MatthiasG
sumber
Ini adalah jawaban yang akurat
abzarak
7

Tidak banyak gunanya mendeklarasikan array tanpa ukuran. Array adalah tentang ukuran . Ketika Anda mendeklarasikan array ukuran tertentu, Anda menentukan jumlah slot tetap yang tersedia dalam koleksi yang dapat menampung barang-barang, dan karenanya memori dialokasikan. Untuk menambahkan sesuatu ke dalamnya, Anda harus tetap menginisialisasi ulang array yang ada (bahkan jika Anda mengubah ukuran array, lihat utas ini ). Salah satu kasus langka di mana Anda ingin menginisialisasi array kosong adalah dengan melewatkan array sebagai argumen.

Jika Anda ingin mendefinisikan koleksi ketika Anda tidak tahu ukurannya mungkin berapa, array bukan pilihan Anda, tetapi sesuatu seperti List<T>atau serupa.

Yang mengatakan, satu-satunya cara untuk mendeklarasikan array tanpa menentukan ukuran adalah dengan memiliki array kosong ukuran 0 . Hemant dan Alex Dn menyediakan dua cara. Alternatif lain yang lebih sederhana adalah dengan :

string[] a = { };

[ Elemen-elemen di dalam braket harus secara implisit dapat dikonversi ke tipe yang ditentukan, misalnya,string[] a = { "a", "b" }; ]

Atau yang lain:

var a = Enumerable.Empty<string>().ToArray();

Ini cara yang lebih deklaratif :

public static class Array<T>
{
    public static T[] Empty()
    {
        return Empty(0);
    }

    public static T[] Empty(int size)
    {
        return new T[size];
    }
}

Sekarang Anda dapat menelepon:

var a = Array<string>.Empty();

//or

var a = Array<string>.Empty(5);
nawfal
sumber
1
Saya tidak bisa memikirkan penggunaan apa pun kecuali ketika Anda harus melewatkan array sebagai parameter. Ada beberapa kasus dalam refleksi di mana metode menerima array objek dan Anda mungkin ingin meneruskan array kosong untuk melakukan aksi default. Saya akan mengedit jawaban saya.
nawfal
Misalnya Anda memiliki antarmuka yang diimplementasikan oleh beberapa kelas mengembalikan IEnumerable dan salah satu implementasinya tidak memiliki elemen untuk metode dan mengembalikan array kosong misalnya.
Ignacio Soler Garcia
@IgnacioSolerGarcia Saya akan mengembalikan array dalam kasus itu jika dan hanya jika itu adalah aplikasi yang sangat kritis. Saya akan mengatakan array sudah usang dan harus dihindari jika Anda bisa. Lihat ini oleh Lippert dan pertanyaan SO ini
nawfal
Perlu diingat bahwa tipe yang dikembalikan adalah IEnumerable sehingga array hanya-baca dan tidak dimaksudkan untuk berubah. Mengapa saya mengembalikan Daftar dalam kasus ini misalnya?
Ignacio Soler Garcia
1
Kasus penggunaan untuk array kosong adalah sederhana - ketika Anda ingin mengisinya dengan objek dan Anda tidak tahu berapa banyak Anda akan menambahkan!
vapcguy
6

Sederhana dan elegan!

string[] array = {}
disklosr
sumber
Saya akan berubah arraymenjadi adil a, seperti arraykata kunci saat ditulis dengan huruf besar. Hanya praktik buruk untuk menggunakan nama kata kunci sebagai nama variabel - bahkan jika kasusnya berbeda. Dan pada dasarnya sama dengan jawaban saya kecuali yang saya miliki String.Emptydi sana.
vapcguy
1
1. array bukan kata kunci ac #. Array adalah kelas dan bukan kata kunci 2. "a" juga merupakan praktik buruk (bahkan mungkin lebih buruk praktik buruk daripada menggunakan kata kunci)
disklosr
Menjadi teknis. Kelas, kata kunci, mendefinisikan jenis objek dan masih buruk. Mengapa menurut Anda aitu buruk?
vapcguy
1
Karena nama variabel non-deskriptif dan satu huruf adalah praktik yang buruk karena mereka tidak menyampaikan alasan untuk mendefinisikannya. "array" tentu saja nama yang lebih baik daripada "a". Nama yang lebih baik adalah "emptyArray".
disklosr
4

string[] a = new string[0];

atau notasi singkat:

string[] a = { };

Cara yang disukai sekarang adalah:

var a = Array.Empty<string>();

Saya telah menulis ekspresi reguler pendek yang dapat Anda gunakan di Visual Studio jika Anda ingin mengganti alokasi panjang nol misalnya new string[0]. Gunakan Cari (cari) di Visual Studio dengan opsi Ekspresi Reguler dihidupkan:

new[ ][a-zA-Z0-9]+\[0\]

Sekarang Temukan Semua atau F3 (Temukan Selanjutnya) dan ganti semua dengan Array.Empty <…> ()!

juFo
sumber
3

Anda dapat menentukan ukuran array saat runtime .

Ini akan memungkinkan Anda untuk melakukan apa pun untuk menghitung ukuran array secara dinamis. Tapi, begitu didefinisikan ukurannya tidak berubah.

Array a = Array.CreateInstance(typeof(string), 5);
radarbob
sumber
4
Kenapa melakukan semua itu? Saat runtime Anda dapat menentukan ukuran array dari variabel secara normal:int i = 5; string[] a = new string[i];
Kevin Brock
Yah, saya kira dengan obat generik ini tampaknya sudah usang.
radarbob
2

Saya sudah mencoba:

string[] sample = new string[0];

Tapi saya hanya bisa memasukkan satu string ke dalamnya, dan kemudian saya mendapat kesalahan exceptionOutOfBound, jadi saya cukup memberikan ukuran untuk itu, seperti

string[] sample = new string[100];

Atau cara lain yang cocok untuk saya:

List<string> sample = new List<string>();

Menetapkan Nilai untuk daftar:

sample.Add(your input);
Cs_Lu
sumber
1

Seperti yang saya tahu Anda tidak dapat membuat array tanpa ukuran, tetapi Anda bisa menggunakannya

List<string> l = new List<string>() 

dan kemudian l.ToArray().

Alex Dn
sumber
1

Menggabungkan saran @nawfal & @Kobi:

namespace Extensions
{
    /// <summary> Useful in number of places that return an empty byte array to avoid unnecessary memory allocation. </summary>
    public static class Array<T>
    {
        public static readonly T[] Empty = new T[0];
    }
}

Contoh penggunaan:

Array<string>.Empty

UPDATE 2019-05-14

(kredit ke @Jaider ty)

Lebih baik gunakan .Net API:

public static T[] Empty<T> ();

https://docs.microsoft.com/en-us/dotnet/api/system.array.empty?view=netframework-4.8

Berlaku untuk:

.NET Core: 3.0 Preview 5 2.2 2.1 2.0 1.1 1.0

.NET Framework: 4.8 4.7.2 4.7.1 4.7 4.6.2 4.6.1 4.6

.NET Standard: 2.1 Preview 2.0 1.6 1.5 1.4 1.3

...

HTH

ShloEmi
sumber
1
Di .NET Core 2, sudah ada ekstensi untuk itu,arr = Array.Empty<string>();
Jaider
iirc, dalam .NetStandart [4.something] - ada juga.
ShloEmi
0

Anda dapat melakukan:

string[] a = { String.Empty };

Catatan: OP berarti tidak harus menentukan ukuran, tidak membuat array tidak masuk akal

vapcguy
sumber
8
Bukankah ini akan membuat array string dengan panjang 1?
Sumner Evans
Benar, tapi sudah dihapus. Dan OP diminta untuk mendeklarasikan array tanpa harus menyatakan ukuran - ini cocok untuk itu.
vapcguy
Dan itu pantas dipuji, mengapa? OP berarti tidak perlu specifyukuran, tidak membuat array sizeless.
vapcguy
1
@ vapcguy saya adalah downvoter. Saya menyesalinya. Saya telah mengedit jawaban Anda untuk membatalkan downvote saya. Komentar Anda membuat pertanyaan itu agak meragukan. Tidak yakin apakah itu yang dimaksud OP.
nawfal
4
OP meminta array kosong . Array ini tidak kosong.
Keith
0

Ini adalah contoh dunia nyata. Dalam hal ini perlu menginisialisasi array foundFilesterlebih dahulu ke nol panjang.

(Seperti yang ditekankan dalam jawaban lain: Ini menginisialisasi bukan elemen dan terutama bukan elemen dengan indeks nol karena itu berarti array memiliki panjang 1. Array memiliki panjang nol setelah baris ini!).

Jika bagian = string[0]tersebut dihilangkan, ada kesalahan kompiler!

Ini karena blok tangkap tanpa rethrow. Compiler C # mengenali jalur kode, bahwa fungsi tersebut Directory.GetFiles()dapat membuang Pengecualian, sehingga array dapat diinisialisasi.

Sebelum ada yang mengatakan, tidak mengubah kembali pengecualian akan menjadi penanganan kesalahan yang buruk: Ini tidak benar. Penanganan kesalahan harus sesuai dengan persyaratan.

Dalam hal ini diasumsikan bahwa program harus melanjutkan dalam kasus direktori yang tidak dapat dibaca, dan tidak rusak- contoh terbaik adalah fungsi yang melintasi struktur direktori. Di sini penanganan kesalahan hanya mencatatnya. Tentu saja ini bisa dilakukan dengan lebih baik, misalnya mengumpulkan semua direktori dengan GetFiles(Dir)panggilan gagal dalam daftar, tetapi ini akan mengarah terlalu jauh di sini.

Cukup dengan menyatakan bahwa menghindar throwadalah skenario yang valid, dan array harus diinisialisasi dengan panjang nol. Ini akan cukup untuk melakukan ini di blok tangkap, tapi ini akan menjadi gaya yang buruk.

Panggilan untuk GetFiles(Dir)mengubah ukuran array.

string[] foundFiles= new string[0];
string dir = @"c:\";
try
{
    foundFiles = Directory.GetFiles(dir);  // Remark; Array is resized from length zero
}
// Please add appropriate Exception handling yourself
catch (IOException)
{
  Console.WriteLine("Log: Warning! IOException while reading directory: " + dir);
  // throw; // This would throw Exception to caller and avoid compiler error
}

foreach (string filename in foundFiles)
    Console.WriteLine("Filename: " + filename);
Philm
sumber