Di .NET Core dan .NET> 4 ada metode parse generik :
Enum.TryParse("Active", out StatusEnum myStatus);
Ini juga termasuk out
variabel inline baru C # 7 , jadi ini melakukan try-parse, konversi ke tipe enum eksplisit dan menginisialisasi + mengisi myStatus
variabel.
Jika Anda memiliki akses ke C # 7 dan .NET terbaru, ini adalah cara terbaik.
Jawaban Asli
Di .NET agak jelek (sampai 4 atau lebih):
StatusEnum MyStatus = (StatusEnum) Enum.Parse(typeof(StatusEnum), "Active", true);
Saya cenderung menyederhanakan ini dengan:
public static T ParseEnum<T>(string value)
{
return (T) Enum.Parse(typeof(T), value, true);
}
Maka saya bisa melakukan:
StatusEnum MyStatus = EnumUtil.ParseEnum<StatusEnum>("Active");
Salah satu opsi yang disarankan dalam komentar adalah menambahkan ekstensi, yang cukup sederhana:
public static T ToEnum<T>(this string value)
{
return (T) Enum.Parse(typeof(T), value, true);
}
StatusEnum MyStatus = "Active".ToEnum<StatusEnum>();
Terakhir, Anda mungkin ingin memiliki enum default untuk digunakan jika string tidak dapat diuraikan:
public static T ToEnum<T>(this string value, T defaultValue)
{
if (string.IsNullOrEmpty(value))
{
return defaultValue;
}
T result;
return Enum.TryParse<T>(value, true, out result) ? result : defaultValue;
}
Yang membuat ini panggilan:
StatusEnum MyStatus = "Active".ToEnum(StatusEnum.None);
Namun, saya akan berhati-hati menambahkan metode ekstensi seperti ini string
sebagai (tanpa kontrol namespace) itu akan muncul di semua contoh string
apakah mereka memegang enum atau tidak (jadi 1234.ToString().ToEnum(StatusEnum.None)
akan valid tetapi tidak masuk akal). Sering kali yang terbaik adalah menghindari kekacauan kelas inti Microsoft dengan metode tambahan yang hanya berlaku dalam konteks yang sangat spesifik kecuali jika seluruh tim pengembangan Anda memiliki pemahaman yang sangat baik tentang apa yang dilakukan ekstensi tersebut.
Gunakan
Enum.TryParse<T>(String, T)
(≥ .NET 4.0):Itu dapat disederhanakan lebih jauh dengan tipe parameter C # 7.0 di sebaris :
sumber
Parse
melempar pengecualian penjelas untuk apa yang salah dengan konversi (nilainyanull
, kosong atau tidak ada konstanta enum yang sesuai), yang jauh lebih baik daripadaTryParse
nilai pengembalian boolean (yang menekan kesalahan konkret)var result = Enum.TryParse<System.DayOfWeek>("55", out var parsedEnum);
Perhatikan bahwa kinerja
Enum.Parse()
mengerikan, karena dilaksanakan melalui refleksi. (Hal yang sama berlaku untukEnum.ToString
yang sebaliknya.)Jika Anda perlu mengonversi string ke Enums dalam kode yang peka terhadap kinerja, taruhan terbaik Anda adalah membuat
Dictionary<String,YourEnum>
saat startup dan menggunakannya untuk melakukan konversi.sumber
Anda sedang mencari Enum.Parse .
sumber
Anda dapat menggunakan metode ekstensi sekarang:
Dan Anda dapat memanggil mereka dengan kode di bawah ini (di sini,
FilterType
adalah tipe enum):sumber
Jadi jika Anda memiliki mood enum bernama itu akan terlihat seperti ini:
sumber
WASPADALAH:
Enum.(Try)Parse()
menerima beberapa argumen yang dipisahkan koma, dan menggabungkannya dengan biner 'atau'|
. Anda tidak dapat menonaktifkan ini dan menurut saya Anda hampir tidak pernah menginginkannya.Bahkan jika
Three
tidak didefinisikan,x
masih akan mendapatkan nilai int3
. Itu bahkan lebih buruk: Enum.Parse () dapat memberi Anda nilai yang bahkan tidak ditentukan untuk enum!Saya tidak ingin mengalami konsekuensi dari pengguna, mau tidak mau, memicu perilaku ini.
Selain itu, seperti yang disebutkan oleh orang lain, kinerja kurang dari ideal untuk enum besar, yaitu linier dalam jumlah nilai yang mungkin.
Saya menyarankan yang berikut ini:
sumber
Enum.(Try)Parse accepts multiple, comma-separated arguments, and combines them with binary 'or'
. Berarti Anda dapat mengatur nilai enum Anda sebagai kekuatan 2 dan Anda memiliki cara yang sangat mudah untuk mem-parsing beberapa flag boolean, mis. "GunakanSSL, NoRetries, Sync". Bahkan mungkin memang dirancang untuk apa.Enum.Parse adalah teman Anda:
sumber
Anda dapat memperluas jawaban yang diterima dengan nilai default untuk menghindari pengecualian:
Maka Anda menyebutnya seperti:
Jika nilai default bukan enum, Enum.TryParse akan gagal dan melempar pengecualian yang ditangkap.
Setelah bertahun-tahun menggunakan fungsi ini dalam kode kami di banyak tempat, mungkin ada baiknya menambahkan informasi bahwa operasi ini membutuhkan kinerja!
sumber
defaultValue
dan metode tipe pengembalian keduanya bertipeT
. Jika jenisnya berbeda, Anda akan menerima kesalahan waktu kompilasi: "tidak dapat mengonversi dari 'ConsoleApp1.Size' ke 'ConsoleApp1.Color'" atau apa pun jenisnya.Kami tidak dapat menerima input yang benar-benar valid, dan menggunakan variasi jawaban @ Keith ini:
sumber
sumber
Mengurai string ke TEnum tanpa mencoba / menangkap dan tanpa metode TryParse () dari .NET 4.5
sumber
Kode super sederhana menggunakan TryParse:
sumber
Saya suka solusi metode ekstensi ..
Di sini di bawah ini implementasi saya dengan tes.
sumber
==================== Program Lengkap ====================
sumber
Saya menggunakan kelas (versi yang sangat diketik dari Enum dengan parsing dan peningkatan kinerja). Saya menemukannya di GitHub, dan seharusnya berfungsi juga untuk .NET 3.5. Ini memiliki beberapa overhead memori karena buffer kamus.
Blogpost adalah Enums - Sintaks yang lebih baik, peningkatan kinerja dan TryParse di NET 3.5 .
Dan kode: https://github.com/damieng/DamienGKit/blob/master/CSharp/DamienG.Library/System/EnumT.cs
sumber
Untuk kinerja, ini mungkin membantu:
sumber
Saya menemukan bahwa di sini kasus dengan nilai enum yang memiliki nilai EnumMember tidak dipertimbangkan. Jadi di sini kita mulai:
Dan contoh dari enum itu:
sumber
Anda harus menggunakan Enum.Parse untuk mendapatkan nilai objek dari Enum, setelah itu Anda harus mengubah nilai objek ke nilai enum tertentu. Melakukan casting ke nilai enum dapat dilakukan dengan menggunakan Convert.ChangeType. Silakan lihat potongan kode berikut
sumber
Coba contoh ini:
Dalam sampel ini Anda dapat mengirim setiap string, dan mengatur
Enum
. Jika AndaEnum
memiliki data yang Anda inginkan, kembalikan itu sebagaiEnum
tipe Anda .sumber
newModel
pada setiap baris, jadi jika itu berisi tanda hubung, itu tidak akan diganti. Selain itu, Anda tidak perlu memeriksa apakah string tersebut mengandung sesuatu, Anda dapat memanggilReplace
saja:var newModel = model.Replace("-", "").Replace(" ", "");
Tidak yakin kapan ini ditambahkan tetapi pada kelas Enum sekarang ada a
Parse<TEnum>(stringValue)
Digunakan seperti itu dengan contoh dalam pertanyaan:
var MyStatus = Enum.Parse<StatusEnum >("Active")
atau mengabaikan casing dengan:
var MyStatus = Enum.Parse<StatusEnum >("active", true)
Berikut adalah metode terurai yang digunakan:
sumber
sumber
sumber
Jika nama properti berbeda dari apa yang Anda inginkan (mis. Perbedaan bahasa), Anda dapat melakukannya seperti ini:
MyType.cs
EnumExtensions.cs
Program.cs
sumber