Jawaban:
Ya, tetapi Anda harus mendeklarasikannya readonly
daripada const
:
public static readonly string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };
Alasannya adalah bahwa const
hanya dapat diterapkan ke bidang yang nilainya diketahui pada waktu kompilasi. Penginisialisasi array yang Anda tunjukkan bukan ekspresi konstan dalam C #, sehingga menghasilkan kesalahan kompilator.
Mendeklarasikannya readonly
memecahkan masalah itu karena nilainya tidak diinisialisasi hingga waktu berjalan (meskipun dijamin telah diinisialisasi sebelum pertama kali array digunakan).
Bergantung pada apa yang akhirnya ingin Anda capai, Anda mungkin juga mempertimbangkan untuk mendeklarasikan enum:
public enum Titles { German, Spanish, Corrects, Wrongs };
readonly static
memiliki kemiripan semantik yang diminta.
static
tidak diperlukan untuk membuatnya berfungsi, itu hanya menambah kemungkinan referensi Titles
tanpa memiliki instance, tetapi menghapus kemungkinan untuk mengubah nilai untuk contoh yang berbeda (misalnya Anda dapat memiliki konstruktor dengan parameter tergantung pada mana Anda mengubah nilai readonly
bidang itu).
Anda dapat mendeklarasikan array sebagai readonly
, tetapi perlu diingat bahwa Anda dapat mengubah elemen readonly
array.
public readonly string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };
...
Titles[0] = "bla";
Pertimbangkan menggunakan enum, seperti yang disarankan Cody, atau IList.
public readonly IList<string> ITitles = new List<string> {"German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();
const
BUKAN readonly
...
Anda tidak dapat membuat array 'const' karena array adalah objek dan hanya dapat dibuat saat runtime dan entitas const diselesaikan pada waktu kompilasi.
Yang bisa Anda lakukan adalah mendeklarasikan array sebagai "readonly". Ini memiliki efek yang sama dengan const kecuali nilainya dapat diatur pada saat runtime. Ini hanya dapat ditetapkan sekali dan setelah itu nilai readonly (ie const).
const int[] a = null;
yang tidak terlalu berguna, tetapi memang merupakan contoh konstanta array.
Sejak C # 6 Anda dapat menulis seperti:
public static string[] Titles => new string[] { "German", "Spanish", "Corrects", "Wrongs" };
Lihat juga: C #: C # 6.0 yang Baru dan yang Disempurnakan (khususnya bab "Fungsi dan Properti yang Berekspresi")
Ini akan membuat properti statis read-only, tetapi masih memungkinkan Anda untuk mengubah konten array yang dikembalikan, tetapi ketika Anda memanggil properti lagi, Anda akan mendapatkan array asli yang tidak diubah lagi.
Untuk klarifikasi, kode ini sama dengan (atau sebenarnya singkatan):
public static string[] Titles
{
get { return new string[] { "German", "Spanish", "Corrects", "Wrongs" }; }
}
Harap dicatat bahwa ada kelemahan pada pendekatan ini: Array baru sebenarnya dipakai pada setiap referensi, jadi jika Anda menggunakan array yang sangat besar, ini mungkin bukan solusi yang paling efisien. Tetapi jika Anda menggunakan kembali array yang sama (dengan meletakkannya di atribut pribadi misalnya) itu lagi akan membuka kemungkinan untuk mengubah konten array.
Jika Anda ingin memiliki array (atau daftar) yang tidak dapat diubah, Anda juga dapat menggunakan:
public static IReadOnlyList<string> Titles { get; } = new string[] { "German", "Spanish", "Corrects", "Wrongs" };
Tapi, ini masih memiliki risiko untuk berubah, karena Anda masih bisa mengembalikannya ke string [] dan mengubah isinya, seperti:
((string[]) Titles)[1] = "French";
Titles[0]
, misalnya - pada dasarnya, upaya penugasan diam-diam diabaikan. Dikombinasikan dengan inefisiensi menciptakan array setiap waktu, saya bertanya-tanya apakah pendekatan ini bahkan layak ditampilkan. Sebaliknya, pendekatan ke-2 adalah efisien, dan Anda harus keluar dari jalan untuk mengalahkan kekekalan.
Jika Anda mendeklarasikan array di belakang antarmuka IReadOnlyList, Anda mendapatkan array konstan dengan nilai konstan yang dideklarasikan pada saat runtime:
public readonly IReadOnlyList<string> Titles = new [] {"German", "Spanish", "Corrects", "Wrongs" };
Tersedia dalam .NET 4.5 dan lebih tinggi.
Solusi .NET Framework v4.5 + yang meningkatkan jawaban tdbeckett :
using System.Collections.ObjectModel;
// ...
public ReadOnlyCollection<string> Titles { get; } = new ReadOnlyCollection<string>(
new string[] { "German", "Spanish", "Corrects", "Wrongs" }
);
Catatan: Mengingat bahwa kumpulan itu konstan secara konseptual, mungkin masuk akal static
untuk menyatakannya di tingkat kelas .
Di atas:
Menginisialisasi bidang dukungan implisit properti sekali dengan array.
Perhatikan bahwa { get; }
- yaitu, mendeklarasikan hanya pengambil properti - adalah yang membuat properti itu sendiri hanya baca-saja (mencoba untuk menggabungkan readonly
dengan { get; }
sebenarnya adalah kesalahan sintaksis).
Atau, Anda bisa menghilangkan { get; }
dan menambahkan readonly
untuk membuat bidang alih-alih properti, seperti dalam pertanyaan, tetapi mengekspos anggota data publik sebagai properti daripada bidang adalah kebiasaan yang baik untuk dibentuk.
Membuat struktur mirip array (memungkinkan akses yang diindeks ) yang benar-benar dan kuat hanya-baca (konseptual konstan, sekali dibuat), keduanya berkenaan dengan:
IReadOnlyList<T>
solusi, di mana sebuah (string[])
cor dapat digunakan untuk mendapatkan akses tulis ke unsur-unsur , seperti yang ditunjukkan pada mjepsen ini jawaban yang membantu . IReadOnlyCollection<T>
antarmuka , yang, meskipun kesamaan nama ke kelas ReadOnlyCollection
, bahkan tidak mendukung akses yang diindeks , membuatnya secara fundamental tidak cocok untuk menyediakan akses seperti array.)IReadOnlyCollection
tidak mendukung akses yang diindeks, sehingga tidak dapat digunakan di sini. Selain itu, seperti IReadOnlyList
(yang memang memiliki akses terindeks), ia rentan terhadap manipulasi elemen dengan kembali ke string[]
. Dengan kata lain: ReadOnlyCollection
(yang Anda tidak bisa melemparkan array string ke) adalah solusi yang paling kuat. Tidak menggunakan pengambil adalah sebuah opsi (dan saya telah memperbarui jawaban untuk mencatatnya), tetapi dengan data publik mungkin lebih baik tetap menggunakan properti.
Untuk kebutuhan saya, saya mendefinisikan static
array, bukannya tidak mungkin const
dan berfungsi:
public static string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };
const
dari contoh OP juga berfungsi, tetapi itu (atau jawaban Anda) memungkinkan untuk mengubah keduanya: Titles
instance dan nilai apa pun. Jadi apa gunanya jawaban ini?
readonly
const
/ readonly
pertimbangan, membuatnya berfungsi (seperti jika const
itu adalah kesalahan sintaksis). Bagi sebagian orang itu sepertinya jawaban yang berharga (mungkin mereka juga mencoba menggunakan const
secara tidak sengaja?).
Anda bisa mengambil pendekatan yang berbeda: mendefinisikan string konstan untuk mewakili array Anda dan kemudian membagi string menjadi sebuah array ketika Anda membutuhkannya, misalnya
const string DefaultDistances = "5,10,15,20,25,30,40,50";
public static readonly string[] distances = DefaultDistances.Split(',');
Pendekatan ini memberi Anda konstanta yang dapat disimpan dalam konfigurasi dan dikonversi ke array saat diperlukan.
Demi kelengkapan, sekarang kami juga memiliki ImmutableArays yang kami miliki. Ini harus benar-benar abadi:
public readonly static ImmutableArray<string> Tiles = ImmutableArray.Create(new[] { "German", "Spanish", "Corrects", "Wrongs" });
Membutuhkan referensi System.Collections.Immutable NuGet
https://msdn.microsoft.com/en-us/library/mt452182(v=vs.111).aspx
Ini adalah cara untuk melakukan apa yang Anda inginkan:
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
public ReadOnlyCollection<string> Titles { get { return new List<string> { "German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();}}
Ini sangat mirip dengan melakukan array readonly.
public static readonly ReadOnlyCollection<String> Titles = new List<String> { "German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();
; tidak perlu membuat ulang daftar di setiap pengambilan jika Anda menjadikannya ReadOnlyCollection.
Ini satu-satunya jawaban yang benar. Saat ini Anda tidak dapat melakukan ini.
Semua jawaban lain menyarankan menggunakan variabel read-only statis yang mirip dengan , tetapi tidak sama dengan konstanta. Konstanta sulit dikodekan ke dalam rakitan. Variabel read only statis dapat disetel sekali, mungkin sebagai objek diinisialisasi.
Ini kadang-kadang dipertukarkan, tetapi tidak selalu.
Sebagai alternatif, untuk mengatasi masalah elemen-dapat-dimodifikasi dengan array hanya baca, Anda dapat menggunakan properti statis sebagai gantinya. (Elemen individu masih dapat diubah, tetapi perubahan ini hanya akan dilakukan pada salinan lokal array.)
public static string[] Titles
{
get
{
return new string[] { "German", "Spanish", "Corrects", "Wrongs"};
}
}
Tentu saja, ini tidak akan terlalu efisien karena array string baru dibuat setiap kali.
Alternatif terbaik:
public static readonly byte[] ZeroHash = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };