Saya ingin menulis fungsi yang dapat memvalidasi nilai yang diberikan (diteruskan sebagai string) terhadap kemungkinan nilai dari sebuah enum
. Dalam kasus pertandingan, itu harus mengembalikan contoh enum; jika tidak, itu harus mengembalikan nilai default.
Fungsi tersebut mungkin tidak digunakan secara internal try
/ secaracatch
, yang mengecualikan penggunaan Enum.Parse
, yang memunculkan pengecualian saat diberikan argumen yang tidak valid.
Saya ingin menggunakan sesuatu di sepanjang baris TryParse
fungsi untuk mengimplementasikan ini:
public static TEnum ToEnum<TEnum>(this string strEnumValue, TEnum defaultValue)
{
object enumValue;
if (!TryParse (typeof (TEnum), strEnumValue, out enumValue))
{
return defaultValue;
}
return (TEnum) enumValue;
}
Jawaban:
Seperti yang dikatakan orang lain, Anda harus menerapkannya sendiri
TryParse
. Simon Mourier menyediakan implementasi penuh yang menangani semuanya.Jika Anda menggunakan enum bitfield (yaitu flags), Anda juga harus menangani string seperti
"MyEnum.Val1|MyEnum.Val2"
yang merupakan kombinasi dari dua nilai enum. Jika Anda hanya memanggilEnum.IsDefined
dengan string ini, itu akan mengembalikan false, meskipunEnum.Parse
menanganinya dengan benar.Memperbarui
Seperti yang disebutkan oleh Lisa dan Christian di komentar,
Enum.TryParse
sekarang tersedia untuk C # di .NET4 dan yang lebih baru.MSDN Docs
sumber
Enum.IsDefined akan menyelesaikan berbagai hal. Ini mungkin tidak seefisien TryParse, tetapi ini akan bekerja tanpa penanganan pengecualian.
Perlu dicatat:
TryParse
metode telah ditambahkan di .NET 4.0.sumber
GetNames
. Secara internal, semua metode ini (termasukParse
) digunakanGetHashEntry
, yang melakukan refleksi aktual - sekali. Sisi baiknya, .NET 4.0 memiliki TryParse, dan ini juga umum :)Berikut adalah implementasi khusus dari
EnumTryParse
. Tidak seperti implementasi umum lainnya, ini juga mendukung enum yang ditandai denganFlags
atribut.sumber
Activator.CreateInstance(type)
untuk membuat nilai enum default dan tidakEnum.ToObject(type, 0)
. Hanya masalah selera?Pada akhirnya Anda harus menerapkan ini di sekitar
Enum.GetNames
:Catatan tambahan:
Enum.TryParse
disertakan dalam .NET 4. Lihat di sini http://msdn.microsoft.com/library/dd991876(VS.100).aspxEnum.Parse
penangkapan pengecualian yang dilemparkan ketika gagal. Ini bisa lebih cepat saat kecocokan ditemukan, tetapi kemungkinan akan lebih lambat jika tidak. Bergantung pada data yang Anda proses, ini mungkin atau mungkin bukan peningkatan bersih.EDIT: Baru saja melihat implementasi yang lebih baik untuk ini, yang menyimpan informasi yang diperlukan: http://damieng.com/blog/2010/10/17/enums-better-syntax-improved-performance-and-tryparse-in-net- 3-5
sumber
Flags
atribut.Berdasarkan .NET 4.5
Contoh kode di bawah ini
Referensi: http://www.dotnetperls.com/enum-parse
sumber
Saya memiliki implementasi yang dioptimalkan yang dapat Anda gunakan di UnconstrainedMelody . Secara efektif itu hanya menyimpan daftar nama, tetapi melakukannya dengan cara yang bagus, diketik dengan kuat, dibatasi secara umum :)
sumber
...
sumber
Saat ini tidak ada Enum.TryParse di luar kotak. Ini telah diminta di Connect ( Masih tidak ada Enum.TryParse ) dan mendapat respons yang menunjukkan kemungkinan penyertaan dalam kerangka kerja berikutnya setelah .NET 3.5. Anda harus menerapkan solusi yang disarankan untuk saat ini.
sumber
Satu-satunya cara untuk menghindari penanganan pengecualian adalah dengan menggunakan metode GetNames (), dan kita semua tahu bahwa pengecualian tidak boleh disalahgunakan untuk logika aplikasi umum :)
sumber
Apakah caching sebuah fungsi / kamus yang dibuat secara dinamis diperbolehkan?
Karena Anda tidak (tampaknya) mengetahui jenis enum sebelumnya, eksekusi pertama dapat menghasilkan sesuatu yang dapat dimanfaatkan oleh eksekusi berikutnya.
Anda bahkan dapat menyimpan hasil Enum.GetNames () ke dalam cache
Apakah Anda mencoba mengoptimalkan CPU atau Memori? Apakah Anda benar - benar perlu?
sumber
Seperti yang sudah dikatakan orang lain, jika Anda tidak menggunakan Try & Catch, Anda perlu menggunakan IsDefined atau GetNames ... Berikut adalah beberapa contoh ... pada dasarnya semuanya sama, yang pertama menangani enum nullable. Saya lebih suka yang ke-2 karena ini merupakan ekstensi pada string, bukan enum ... tetapi Anda dapat mencampurnya sesuai keinginan!
sumber
Tidak ada TryParse karena jenis Enum tidak diketahui hingga runtime. Sebuah TryParse yang mengikuti metodologi yang sama seperti misalnya metode Date.TryParse akan memunculkan kesalahan konversi implisit pada parameter ByRef.
Saya sarankan melakukan sesuatu seperti ini:
sumber
Try
metode yang hasilnya mungkin tipe nilai, atau di mananull
mungkin merupakan hasil yang sah (misalnyaDictionary.TryGetValue, which has both such traits), the normal pattern is for a
metode Try` untuk mengembalikanbool
, dan meneruskan hasilnya sebagaiout
parameter. Bagi mereka yang mengembalikan tipe kelas di mananull
bukan hasil yang valid, tidak ada kesulitan menggunakannull
pengembalian untuk menunjukkan kegagalan.Lihat kelas Enum (struct?) Itu sendiri. Ada metode Parse untuk itu tapi saya tidak yakin tentang tryparse.
sumber
Metode ini akan mengonversi jenis enum:
Ia memeriksa jenis yang mendasari dan mendapatkan nama untuk mengurai. Jika semuanya gagal, itu akan mengembalikan nilai default.
sumber