Saya tahu yang berikut ini tidak mungkin karena tipe Pencacahan harus berupa int
enum GroupTypes
{
TheGroup = "OEM",
TheOtherGroup = "CMB"
}
Dari basis data saya, saya mendapatkan bidang dengan kode yang tidak komprehensif ( OEM
dan CMB
s). Saya ingin membuat bidang ini menjadi enum
atau sesuatu yang bisa dimengerti. Karena jika targetnya mudah dibaca, solusinya harus singkat.
Opsi apa lagi yang saya miliki?
Jawaban:
Saya suka menggunakan properti di kelas daripada metode, karena mereka terlihat lebih seperti enum.
Berikut ini contoh untuk seorang Logger:
Lewati nilai string tipe-aman sebagai parameter:
Pemakaian:
sumber
ToString
metode untuk kembaliValue
. Dan kemudian memberikan operator pemeran implisit ke dan dari string.public static implicit operator String(LogCategory category) { return Value; }
.Anda juga dapat menggunakan model ekstensi:
Kelas Ekstensi Anda
pemakaian:
sumber
public static string ToDescriptionString(this Enum ...
yaitu tanpa mengetik secara eksplisit keMyEnum
.Bagaimana kalau menggunakan kelas statis dengan konstanta?
sumber
GroupTypes
sebagai tipe argumen karena ini adalah kelas statis. Itulah masalah yang dipecahkan oleh jawaban Bahkan Mien. Dalam hal ini Anda malah harus memilikivoid DoSomething(string groupType)
, yang berartigroupType
dapat memiliki nilai string apa pun , bahkan nilai yang tidak Anda harapkan, yang berarti Anda harus siap untuk jenis yang tidak valid dan memutuskan bagaimana menanganinya (mis. dengan melemparkan pengecualian). Bahkan jawaban Mien memecahkan itu dengan membatasi jumlah input yang valid ke opsi yang ditentukan olehLogCategory
kelas.Anda bisa menambahkan atribut ke item dalam penghitungan dan kemudian menggunakan refleksi untuk mendapatkan nilai dari atribut.
Anda harus menggunakan specifier "bidang" untuk menerapkan atribut, seperti:
Anda kemudian akan merefleksikan bidang statis dari jenis enum (dalam hal ini GroupTypes) dan mendapatkan
DescriptionAttribute
nilai yang Anda cari menggunakan refleksi:Saya memilih untuk mengembalikan
DescriptionAttribute
sendiri di atas, jika Anda ingin dapat menentukan apakah atribut tersebut diterapkan atau tidak.sumber
Anda dapat melakukannya dengan sangat mudah sebenarnya. Gunakan kode berikut.
Kemudian ketika Anda ingin mendapatkan nilai string dari setiap elemen enum cukup gunakan baris kode berikut.
Saya telah menggunakan metode ini dengan sukses di masa lalu, dan saya juga menggunakan kelas konstanta untuk menahan konstanta string, keduanya bekerja dengan cukup baik, tetapi saya cenderung lebih suka ini.
sumber
Coba tambahkan konstanta ke kelas statis. Anda tidak berakhir dengan suatu Tipe, tetapi Anda akan memiliki konstanta yang dapat dibaca dan diatur:
sumber
Buat enum kedua, untuk DB Anda yang berisi yang berikut ini:
Sekarang, Anda bisa menggunakan Enum.Parse untuk mengambil nilai DBGroupTypes yang benar dari string "OEM" dan "CMB". Anda kemudian dapat mengonversikannya ke int dan mengambil nilai yang benar dari penghitungan yang tepat yang ingin Anda gunakan lebih lanjut dalam model Anda.
sumber
Gunakan kelas.
Sunting: Contoh yang lebih baik
sumber
Cara lain untuk mengatasi masalah, adalah memiliki enum dan array string yang akan memetakan nilai enum dengan daftar string:
Anda dapat menggunakannya seperti ini:
Ini akan meminta CMB
PROS:
CONS:
sumber
Berikut adalah metode ekstensi yang saya gunakan untuk mendapatkan nilai enum sebagai string. Pertama di sini adalah enum.
Atribut Deskripsi berasal dari System.ComponentModel.
Dan inilah metode ekstensi saya:
Sekarang, Anda dapat mengakses enum sebagai nilai string menggunakan kode berikut:
sumber
Sudahkah Anda mempertimbangkan tabel pencarian menggunakan Kamus?
Anda kemudian dapat menggunakan GroupTypeLookup.TryGetValue () untuk mencari string ketika Anda membacanya.
sumber
sumber
C # tidak mendukung string yang disebutkan, tetapi untuk sebagian besar situasi Anda dapat menggunakan Daftar atau Kamus untuk mendapatkan efek yang diinginkan.
Misalnya untuk mencetak hasil lulus / gagal:
sumber
Saya akan membuatnya menjadi kelas yang menghindari enum sama sekali. Dan kemudian dengan menggunakan typehandler Anda bisa membuat objek saat Anda mengambilnya dari db.
YAITU:
sumber
Saya hanya akan membuat kamus dan menggunakan kode sebagai kuncinya.
Sunting: Untuk mengatasi komentar tentang melakukan pencarian terbalik (menemukan kunci), ini tidak akan sangat efisien. Jika ini perlu, saya akan menulis kelas baru untuk mengatasinya.
sumber
Pertanyaan pertama saya - Apakah Anda memiliki akses ke Database itu sendiri? Ini harus dinormalisasi dalam database, idealnya, jika tidak, solusi apa pun akan rentan terhadap kesalahan. Dalam pengalaman saya, bidang data yang penuh dengan "OEM" dan "CMB" cenderung berakhir dengan hal-hal seperti "oem" dan 'data sampah' lainnya bercampur seiring waktu .... Jika Anda dapat menormalkannya, Anda dapat menggunakan kunci di tabel yang berisi elemen sebagai Enum Anda, dan Anda selesai, dengan struktur yang jauh lebih bersih.
Jika itu tidak tersedia, saya akan membuat Enum Anda, dan membuat kelas untuk mengurai string Anda ke dalam Enum untuk Anda. Ini setidaknya akan memberi Anda beberapa fleksibilitas dalam menangani entri yang tidak standar dan jauh lebih fleksibel untuk menjebak atau menangani kesalahan daripada melakukan pemecahan masalah menggunakan Enum.Parse / Reflection / dll. Kamus akan berfungsi, tetapi bisa rusak jika Anda memiliki masalah kasus, dll.
Saya akan merekomendasikan menulis kelas sehingga Anda dapat melakukannya:
Ini menjaga sebagian besar keterbacaan Anda tanpa harus mengubah DB.
sumber
Jika saya mengerti dengan benar, Anda perlu konversi dari string ke enum:
Anda dapat membuatnya lebih mewah dengan obat generik untuk tipe enum jika diinginkan.
sumber
Di VS 2015, Anda dapat menggunakan nama
Pemakaian:
sumber
Tweak kecil untuk metode Ekstensi Glennular, sehingga Anda dapat menggunakan ekstensi pada hal lain selain dari ENUM;
Atau Menggunakan Linq
sumber
Mengikuti jawaban @Even Mien saya telah mencoba untuk melangkah lebih jauh dan membuatnya menjadi Generic, saya sepertinya hampir ada tetapi satu case masih menolak dan saya mungkin dapat menyederhanakan kode saya sedikit.
Saya mempostingnya di sini jika ada yang melihat bagaimana saya dapat meningkatkan dan terutama membuatnya berfungsi karena saya tidak dapat menetapkannya dari string
Sejauh ini saya memiliki hasil sebagai berikut:
Di mana keajaiban terjadi:
Saya hanya kemudian harus menyatakan ini untuk enum saya:
sumber
Baru di .Net Core 3.0 / C # 8.0 (jika lingkungan kerja Anda memungkinkan Anda untuk memutakhirkan proyek Anda) adalah pernyataan sakelar tangan pendek yang terlihat agak enum-ish. Pada akhirnya, itu adalah pernyataan beralih membosankan lama yang sama yang telah kami gunakan selama bertahun-tahun.
Satu-satunya perbedaan nyata di sini adalah bahwa pergantian pernyataan mendapat setelan baru.
Anda akan melihat bahwa kode di atas yang saya salin dari sini , sebenarnya menggunakan enum sebagai param.
Ini bukan apa yang Anda inginkan (dan percayalah, saya menginginkan sesuatu yang mirip dengan apa yang diminta OP untuk waktu yang lama), tetapi saya benar-benar merasa ini semacam cabang zaitun dari MS. JMO.
Semoga ini bisa membantu seseorang!
sumber
Saya menggunakan struktur seperti disinggung dalam jawaban sebelumnya, tetapi menghilangkan kompleksitas. Bagi saya, ini paling seperti membuat enumerasi string. Ini digunakan dengan cara yang sama bahwa enumerasi digunakan.
Contoh penggunaan:
sumber
Saya bahkan menerapkan beberapa enum seperti yang disarankan oleh @Even (via
class X
danpublic static X
anggota), hanya untuk mengetahui kemudian bahwa hari ini, mulai. Net 4.5, ada metode yang tepatToString()
.Sekarang saya menerapkan kembali semuanya ke enum.
sumber
Ini adalah cara untuk menggunakannya sebagai parameter yang sangat diketik atau sebagai string :
sumber
Anda dapat menggunakan dua enum. Satu untuk database dan yang lainnya untuk dibaca.
Anda hanya perlu memastikan mereka tetap sinkron, yang tampaknya seperti biaya yang kecil. Anda tidak harus mengatur nilai, cukup mengatur posisi yang sama, tetapi pengaturan nilai membuatnya sangat jelas bahwa dua enum terkait dan mencegah kesalahan mengatur ulang anggota enum. Dan komentar membuat kru pemeliharaan tahu ini terkait dan harus tetap sinkron.
Untuk menggunakannya, Anda cukup mengonversi ke kode terlebih dahulu:
Kemudian jika Anda ingin membuatnya lebih nyaman, Anda dapat menambahkan fungsi ekstensi yang hanya berfungsi untuk enum jenis ini:
dan kemudian Anda bisa melakukan:
sumber
enum
perubahan nilai yang dimaksudkan pada satu dapat secara tidak sengaja mengacaukan yang lain.Saya pada dasarnya mencari jawaban Refleksi oleh @ArthurC
Hanya untuk sedikit memperluas jawabannya, Anda dapat membuatnya lebih baik dengan memiliki fungsi generik:
Maka Anda bisa membungkus apa pun yang Anda miliki
atau
sumber
Diambil dari @EvenMien dan ditambahkan di beberapa komentar. (Juga untuk kasus penggunaan saya sendiri)
sumber
Menambahkan kelas ini
Karya ini digunakan
CallerMemberName
untuk meminimalkan pengkodeanMenggunakan:
Menguji:
keluaran:
sumber
Berdasarkan pendapat lain, inilah yang saya kemukakan. Pendekatan ini menghindari keharusan mengetik. Nilai di mana Anda ingin mendapatkan nilai konstan.
Saya memiliki kelas dasar untuk semua string enum seperti ini:
JsonConverter seperti ini:
Dan string enum aktual akan menjadi seperti ini:
Dan dengan ini, Anda bisa menggunakan Color.Red untuk membuat serial ke json tanpa menggunakan properti Value
sumber
Saya tidak membutuhkan sesuatu yang kuat seperti menyimpan string dalam atribut. Saya hanya perlu mengubah sesuatu seperti
MyEnum.BillEveryWeek
menjadi "tagihan setiap minggu" atauMyEnum.UseLegacySystem
menjadi "gunakan sistem warisan" - pada dasarnya membagi enum dengan casing untanya menjadi kata-kata kecil individual.MyEnum.UseLegacySystem.UnCamelCase()
output "gunakan sistem warisan"Jika Anda memiliki beberapa flag yang ditetapkan, itu akan mengubahnya menjadi bahasa Inggris biasa (dibatasi koma kecuali "dan" di tempat koma terakhir).
sumber