Saya mencari dan tidak dapat menemukan duplikat. Jika Anda dapat memberikan tautan, saya akan menghapus pertanyaan ini.
Eric Weilnau,
1
kadang-kadang, menggunakan pernyataan switch bukan praktik terbaik (ketika Anda memiliki enumerasi besar), Anda dapat menggunakan Dict <> sebagai gantinya
Guy L
1
Jika Anda menginginkan kinerja yang lebih baik, Anda dapat menggunakan kelas yang dijelaskan dalam artikel ini codeproject.com/KB/dotnet/enum.aspx . Penggunaan akan terlihat seperti Enum ini <YourEnum> .ToString (YourValue) atau Enum <YourEnum> .ToString ((int) YourValue)
ideafixxxer
5
Pengodean untuk tidak merusak dotfuscation adalah lambang dari ekor yang mengibas-ngibaskan anjing. Produser SW tidak berpikir, "Ayo buat aplikasi hebat jadi dotfuscator ada hubungannya." Dofuscator ada untuk membantu memfasilitasi pengembangan SW. Jika tidak bisa melakukan itu ... bisakah!
micahhoover
Jawaban:
125
Pada C # 6 cara terbaik untuk mendapatkan nama enum adalah nameofoperator baru :
nameof(MyEnum.EnumValue);// Ouputs>"EnumValue"
Ini berfungsi pada waktu kompilasi, dengan enum digantikan oleh string dalam hasil kompilasi, yang pada gilirannya berarti ini adalah cara tercepat yang mungkin.
Penggunaan nama enum apa pun mengganggu kebingungan kode, jika Anda menganggap kebingungan nama enum bermanfaat atau penting - itu mungkin pertanyaan lain.
Ini patut mendapat perhatian lebih. Batasan yang jelas meskipun demikian, yaitu persyaratan untuk input waktu kompilasi. Menurut pendapat saya ini harus lebih disukai bila memungkinkan . 'Ubah nama' dan 'temukan semua referensi' memperhitungkannya juga, berpotensi menghindari string sihir dan konstanta duplikat.
Timo
1
Jadi saya kira itu tidak akan berfungsi ketika nilai enum didefinisikan pada saat runtime? Contoh: MyEnum variableEnum; variableEnum = setEnumValueMethod (); nameof (variableEnum);
Maxter
1
@ Maxax tidak, seperti yang nameof(variableEnum)akan terjadi "variableEnum". Ini mencerminkan (saat membangun) nama bidang / properti / param / variabel bukan nilai .
Keith
kamu. sayangnya tidak berfungsi jika Anda melakukan ini: var someEnumvalue = SomeEnum.FooBar; nameof (someEnumvalue);
Secara jelas
@Sangat ya, itu akan kembali "someEnumValue", sementara Anda harus nameof(SomeEnum.FooBar)mendapatkannya "FooBar".
Enum.GetName mengambil nilai sebagai argumen objek. Ini berarti bahwa nilainya akan kotak dan ini akan membuang sumber daya CPU pada alokasi dan pada pengumpulan sampah. Jika ini dilakukan banyak waktu, Enum.GetName akan memiliki throughput yang jauh lebih rendah daripada caching nilai dalam kamus dan mencari nama di sana.
Berlari
@Bisa jadi apa solusinya, yang mana yang harus digunakan?
shaijut
Ini seharusnya jawabannya
Secara jelas
membuat proyek saya lebih lambat. toString () lebih cepat.
d2k2
29
Dalam pengujian saya, Enum.GetNamelebih cepat dan dengan margin yang layak. ToStringPanggilan internal Enum.GetName. Dari sumber untuk .NET 4.0, yang penting:
publicoverrideStringToString(){returnEnum.InternalFormat((RuntimeType)GetType(),GetValue());}privatestaticStringInternalFormat(RuntimeType eT,Objectvalue){if(!eT.IsDefined(typeof(System.FlagsAttribute),false)){String retval =GetName(eT,value);//<== the oneif(retval ==null)returnvalue.ToString();elsereturn retval;}else{returnInternalFlagsFormat(eT,value);}}
Saya tidak bisa mengatakan itu adalah alasan yang pasti, tetapi tes menyatakan satu lebih cepat dari yang lain. Kedua panggilan tersebut melibatkan tinju (sebenarnya itu adalah panggilan refleksi, Anda pada dasarnya mengambil nama bidang) dan bisa lambat sesuai dengan keinginan Anda.
Semua ini secara internal akhirnya memanggil metode yang disebut InternalGetValueAsString. Perbedaan antara ToStringdan GetNameyang GetNameharus memverifikasi beberapa hal pertama:
Jenis yang Anda masukkan bukan nol.
Jenis yang Anda masukkan sebenarnya adalah enumerasi.
Nilai yang Anda berikan bukan nol.
Nilai yang Anda berikan adalah tipe yang dapat digunakan oleh enumerasi sebagai tipe yang mendasarinya, atau tipe enumerasi itu sendiri. Ini digunakan GetTypepada nilai untuk memeriksa ini.
.ToStringtidak perlu khawatir tentang masalah-masalah di atas, karena ini dipanggil pada instance dari kelas itu sendiri, dan bukan pada versi yang disahkan, oleh karena itu, karena fakta bahwa .ToStringmetode ini tidak memiliki masalah verifikasi yang sama sebagai metode statis, saya akan menyimpulkan itu .ToStringadalah cara tercepat untuk mendapatkan nilai sebagai string.
Di mana Anda memeriksa ini? Apa versi perakitannya? Saya mendapatkan hasil yang sangat berbeda.
nawfal
17
Yang terbaik yang dapat saya temukan adalah pertanyaan yang tidak terkait ini di MSDN , yang berisi potongan XML yang menjawab pertanyaan ini. Setiap metode ini memiliki kelemahan yang sama: mereka memanggil enum.toString(), yang tidak berfungsi dengan baik saat menggunakan Dotfuscation . Kekhawatiran lain tampaknya terkait dengan tinju tidak langsung (GetName dan Format). Sayangnya, saya tidak dapat menemukan alasan kinerja untuk menggunakan salah satu di atas.
Melewati enum kotak ke string.Format () atau fungsi lainnya dapat mengakibatkan enum.ToString()dipanggil. Ini akan menyebabkan masalah saat Dotfuscating. Anda tidak harus menggunakan enum.ToString(), enum.GetNames(), enum.GetName(), enum.Format()atau enum.Parse()untuk mengkonversi enum ke string. Alih-alih, gunakan pernyataan peralihan, dan internasionalkan nama jika perlu.
Format()benar-benar hanya pembungkus sekitar GetName()dengan beberapa fungsi pemformatan (atau InternalGetValueAsString()tepatnya). ToString()hampir sama dengan Format(). Saya pikir GetName()ini pilihan terbaik karena sangat jelas apa yang dilakukannya bagi siapa saja yang membaca sumbernya.
Saya membuat metode ekstensi "Deskripsi" dan melampirkannya pada enum sehingga saya bisa mendapatkan penamaan yang benar-benar user-friendly yang mencakup spasi dan casing. Saya tidak pernah suka menggunakan nilai enum itu sendiri sebagai teks yang dapat ditampilkan karena ini adalah sesuatu yang kami pengembang gunakan untuk membuat kode yang lebih mudah dibaca. Itu tidak dimaksudkan untuk tujuan tampilan UI. Saya ingin dapat mengubah UI tanpa melalui dan mengubah enum di seluruh.
Saya tidak tahu apa metode "pilihan" itu (tanyakan 100 orang dan dapatkan 100 pendapat berbeda) tetapi lakukan apa yang paling sederhana dan apa yang berhasil. GetNameberfungsi tetapi membutuhkan lebih banyak penekanan tombol. ToString()tampaknya melakukan pekerjaan dengan sangat baik.
ToString()memberikan hasil paling jelas dari perspektif keterbacaan, saat menggunakanEnum.GetName() membutuhkan sedikit penguraian mental untuk dengan cepat memahami apa yang coba dilakukan (kecuali jika Anda melihat polanya sepanjang waktu).
Dari sudut pandang kinerja murni, seperti yang sudah disediakan dalam jawaban @ nawfal, Enum.GetName()lebih baik.
Jika kinerja benar-benar tujuan Anda, akan lebih baik untuk menyediakan pencarian sebelumnya (menggunakan Kamus atau pemetaan lainnya).
Dalam C ++ / CLI, ini akan terlihat seperti
Dictionary<String^,MyEnum> mapping;for each (MyEnum field in Enum::GetValues(MyEnum::typeid)){
mapping.Add(Enum::GetName(MyEnum::typeid), field);}
Perbandingan menggunakan enum 100 item dan iterasi 1000000:
Jawaban:
Pada C # 6 cara terbaik untuk mendapatkan nama enum adalah
nameof
operator baru :Ini berfungsi pada waktu kompilasi, dengan enum digantikan oleh string dalam hasil kompilasi, yang pada gilirannya berarti ini adalah cara tercepat yang mungkin.
Penggunaan nama enum apa pun mengganggu kebingungan kode, jika Anda menganggap kebingungan nama enum bermanfaat atau penting - itu mungkin pertanyaan lain.
sumber
nameof(variableEnum)
akan terjadi"variableEnum"
. Ini mencerminkan (saat membangun) nama bidang / properti / param / variabel bukan nilai ."someEnumValue"
, sementara Anda harusnameof(SomeEnum.FooBar)
mendapatkannya"FooBar"
.Bekerja untuk proyek kami ...
sumber
Dalam pengujian saya,
Enum.GetName
lebih cepat dan dengan margin yang layak.ToString
Panggilan internalEnum.GetName
. Dari sumber untuk .NET 4.0, yang penting:Saya tidak bisa mengatakan itu adalah alasan yang pasti, tetapi tes menyatakan satu lebih cepat dari yang lain. Kedua panggilan tersebut melibatkan tinju (sebenarnya itu adalah panggilan refleksi, Anda pada dasarnya mengambil nama bidang) dan bisa lambat sesuai dengan keinginan Anda.
Jika kecepatan tidak terlihat, saya tidak akan peduli dan menggunakannya
ToString
karena menawarkan panggilan yang jauh lebih bersih. Kontrasdengan
sumber
Enum.GetName (...)
Ini adalah metode paling elegan yang dimaksudkan untuk itu.
Meskipun saya tidak melihat masalah dengan panggilan
.ToString()
karena itu hanya lebih pendek.Dengan sintaks C # 6 baru Anda dapat menggunakan:
sumber
Semua ini secara internal akhirnya memanggil metode yang disebut
InternalGetValueAsString
. Perbedaan antaraToString
danGetName
yangGetName
harus memverifikasi beberapa hal pertama:GetType
pada nilai untuk memeriksa ini..ToString
tidak perlu khawatir tentang masalah-masalah di atas, karena ini dipanggil pada instance dari kelas itu sendiri, dan bukan pada versi yang disahkan, oleh karena itu, karena fakta bahwa.ToString
metode ini tidak memiliki masalah verifikasi yang sama sebagai metode statis, saya akan menyimpulkan itu.ToString
adalah cara tercepat untuk mendapatkan nilai sebagai string.sumber
Yang terbaik yang dapat saya temukan adalah pertanyaan yang tidak terkait ini di MSDN , yang berisi potongan XML yang menjawab pertanyaan ini. Setiap metode ini memiliki kelemahan yang sama: mereka memanggil
enum.toString()
, yang tidak berfungsi dengan baik saat menggunakan Dotfuscation . Kekhawatiran lain tampaknya terkait dengan tinju tidak langsung (GetName dan Format). Sayangnya, saya tidak dapat menemukan alasan kinerja untuk menggunakan salah satu di atas.Mengutip dari cuplikan xml ,
sumber
Enum.GetName()
Format()
benar-benar hanya pembungkus sekitarGetName()
dengan beberapa fungsi pemformatan (atauInternalGetValueAsString()
tepatnya).ToString()
hampir sama denganFormat()
. Saya pikirGetName()
ini pilihan terbaik karena sangat jelas apa yang dilakukannya bagi siapa saja yang membaca sumbernya.sumber
Saya membuat metode ekstensi "Deskripsi" dan melampirkannya pada enum sehingga saya bisa mendapatkan penamaan yang benar-benar user-friendly yang mencakup spasi dan casing. Saya tidak pernah suka menggunakan nilai enum itu sendiri sebagai teks yang dapat ditampilkan karena ini adalah sesuatu yang kami pengembang gunakan untuk membuat kode yang lebih mudah dibaca. Itu tidak dimaksudkan untuk tujuan tampilan UI. Saya ingin dapat mengubah UI tanpa melalui dan mengubah enum di seluruh.
sumber
Saya tidak tahu apa metode "pilihan" itu (tanyakan 100 orang dan dapatkan 100 pendapat berbeda) tetapi lakukan apa yang paling sederhana dan apa yang berhasil.
GetName
berfungsi tetapi membutuhkan lebih banyak penekanan tombol.ToString()
tampaknya melakukan pekerjaan dengan sangat baik.sumber
Untuk penggemar VB:
sumber
Ini akan berhasil juga.
sumber
ToString()
memberikan hasil paling jelas dari perspektif keterbacaan, saat menggunakanEnum.GetName()
membutuhkan sedikit penguraian mental untuk dengan cepat memahami apa yang coba dilakukan (kecuali jika Anda melihat polanya sepanjang waktu).Dari sudut pandang kinerja murni, seperti yang sudah disediakan dalam jawaban @ nawfal,
Enum.GetName()
lebih baik.Jika kinerja benar-benar tujuan Anda, akan lebih baik untuk menyediakan pencarian sebelumnya (menggunakan Kamus atau pemetaan lainnya).
Dalam C ++ / CLI, ini akan terlihat seperti
Perbandingan menggunakan enum 100 item dan iterasi 1000000:
sumber
Sederhana: enum nama ke dalam Daftar:
sumber