Mengapa pengindeks statis tidak diizinkan di C #? Saya tidak melihat alasan mengapa mereka tidak diizinkan dan lebih jauh lagi mereka bisa sangat berguna.
Sebagai contoh:
public static class ConfigurationManager
{
public object this[string name]
{
get => ConfigurationManager.getProperty(name);
set => ConfigurationManager.editProperty(name, value);
}
/// <summary>
/// This will write the value to the property. Will overwrite if the property is already there
/// </summary>
/// <param name="name">Name of the property</param>
/// <param name="value">Value to be wrote (calls ToString)</param>
public static void editProperty(string name, object value)
{
var ds = new DataSet();
var configFile = new FileStream("./config.xml", FileMode.OpenOrCreate);
ds.ReadXml(configFile);
if (ds.Tables["config"] == null)
ds.Tables.Add("config");
var config = ds.Tables["config"];
if (config.Rows[0] == null)
config.Rows.Add(config.NewRow());
if (config.Columns[name] == null)
config.Columns.Add(name);
config.Rows[0][name] = value.ToString();
ds.WriteXml(configFile);
configFile.Close();
}
public static void addProperty(string name, object value) =>
ConfigurationManager.editProperty(name, value);
public static object getProperty(string name)
{
var ds = new DataSet();
var configFile = new FileStream("./config.xml", FileMode.OpenOrCreate);
ds.ReadXml(configFile);
configFile.Close();
if (ds.Tables["config"] == null) return null;
var config = ds.Tables["config"];
if (config.Rows[0] == null) return null;
if (config.Columns[name] == null) return null;
return config.Rows[0][name];
}
}
Kode di atas akan sangat diuntungkan dari pengindeks statis. Namun itu tidak dapat dikompilasi karena pengindeks statis tidak diperbolehkan. Mengapa demikian?
foreach (var enum in Enum)
:)Jawaban:
Notasi pengindeks membutuhkan referensi ke
this
. Karena metode statis tidak memiliki referensi ke instance kelas tertentu, Anda tidak dapat menggunakannyathis
, dan akibatnya Anda tidak dapat menggunakan notasi pengindeks pada metode statis.Solusi untuk masalah Anda menggunakan pola tunggal sebagai berikut:
Sekarang Anda dapat memanggil
Utilities.ConfigurationManager["someKey"]
menggunakan notasi pengindeks.sumber
this
dalam pengindeks tidak selalu diperlukan, kemungkinan besar dipilih di atas kata kunci lain karena paling masuk akal. Untuk implementasi statis, sintaks berikut mungkin cukup layak:public object static[string value]
. Tidak perlu menggunakan kata kuncithis
dalam konteks statis.Saya yakin itu dianggap tidak terlalu berguna. Saya pikir itu memalukan juga - contoh yang cenderung saya gunakan adalah Pengkodean, di mana
Encoding.GetEncoding("foo")
bisaEncoding["Foo"]
. Saya tidak berpikir itu akan datang sangat sering, tapi selain dari apa pun hanya terasa sedikit tidak konsisten tidak akan tersedia.Saya harus memeriksanya, tetapi saya curiga itu sudah tersedia dalam IL (Intermediate Language).
sumber
instance
kestatic
dalam IL untuk properti dan metode pengambil pada properti default menghasilkan keluhan ilasmsyntax error at token 'static'
; Saya tidak pandai ikut campur dalam urusan IL tapi itu terdengar seperti setidaknya sebuah inisial tidak.Sebagai solusinya, Anda dapat menentukan pengindeks instance pada objek tunggal / statis (katakanlah bahwa ConfigurationManager adalah tunggal, bukan kelas statis):
sumber
Saya juga membutuhkan (yah, lebih seperti bagus untuk dimiliki) pengindeks statis untuk menyimpan atribut, jadi saya menemukan solusi yang agak canggung:
Di dalam kelas Anda ingin memiliki pengindeks statis (di sini: Elemen), buat subclass dengan nama yang sama + "Dict". Berikan statis hanya baca sebagai instance dari subkelas tersebut, lalu tambahkan pengindeks yang Anda inginkan.
Terakhir, tambahkan kelas sebagai impor statis (oleh karena itu subkelas hanya mengekspos bidang statis).
lalu Anda dapat menggunakannya dengan huruf besar sebagai Jenis, atau tanpa sebagai kamus:
Namun sayangnya, jika seseorang benar-benar menggunakan objek sebagai "value" -Type, maka di bawah ini akan tetap lebih pendek (setidaknya sebagai deklarasi), dan juga menyediakan Typecasting langsung:
sumber
Dengan konstruksi yang lebih baru di C # 6, Anda mungkin menyederhanakan pola singleton dengan badan ekspresi properti. Misalnya, saya menggunakan pintasan berikut yang berfungsi baik dengan code-lense:
Ini memiliki manfaat tambahan karena dapat menemukan-ganti untuk meningkatkan kode lama dan menyatukan akses pengaturan aplikasi Anda.
sumber
Kata kunci ini mengacu pada instance kelas saat ini. Fungsi anggota statis tidak memiliki penunjuk ini. Kata kunci ini dapat digunakan untuk mengakses anggota dari dalam konstruktor, metode instance, dan pengakses instance. (Diambil dari msdn ). Karena ini mereferensikan instance kelas, itu bertentangan dengan sifat statis, karena statis tidak terkait dengan instance kelas.
Salah satu solusinya adalah berikut ini yang memungkinkan Anda menggunakan pengindeks terhadap kamus pribadi sehingga Anda hanya perlu membuat instance baru dan mengakses bagian statis.
Ini memungkinkan Anda untuk melewati seluruh akses ke anggota kelas dan hanya membuat instance dari itu dan mengindeksnya.
sumber
new ()
dapat digunakan untuk nama kualifikasi dari sebuah singleton sebaliknya, seperti.Current
this
kata kunci", dan kedua,this
dalam sintakspublic string this[int index]
secara tegas bahkan tidak menggunakanthis
penunjuk (seperti yang mungkin terjadi dalam tubuh metode contoh) , tetapi hanya penggunaan token lainnyathis
. Sintaksnyapublic static string this[int index]
mungkin terlihat agak berlawanan dengan intuisi, tetapi tetap tidak ambigu.public static string class[int index]
.Alasannya karena cukup sulit untuk memahami apa yang sebenarnya Anda indeks dengan pengindeks statis.
Anda mengatakan bahwa kode akan mendapatkan keuntungan dari pengindeks statis, tetapi apakah itu benar-benar? Yang akan dilakukannya hanyalah mengubah ini:
Menjadi ini:
yang tidak membuat kode menjadi lebih baik dengan cara apa pun; tidak lebih kecil dengan banyak baris kode, tidak lebih mudah untuk menulis berkat pelengkapan otomatis dan kurang jelas, karena menyembunyikan fakta bahwa Anda mendapatkan dan menyetel sesuatu yang Anda sebut 'Properti' dan itu benar-benar memaksa pembaca untuk baca dokumentasi tentang apa sebenarnya yang dikembalikan atau diset oleh pengindeks, karena sama sekali tidak jelas bahwa ini adalah properti yang Anda indeks, sementara dengan keduanya:
Anda dapat membacanya dengan lantang dan segera memahami fungsi kode tersebut.
Ingatlah bahwa kita ingin menulis kode yang mudah (= cepat) dipahami, bukan kode yang cepat ditulis. Jangan salahkan kecepatan Anda meletakkan kode dengan kecepatan Anda menyelesaikan proyek.
sumber