Yang merupakan cara yang disukai untuk mengubah Enum ke String di. NET 3.5?
- Enum.GetName
- Enum.Format
- ToString
Mengapa saya harus memilih salah satu dari ini daripada yang lain? Apakah seseorang berkinerja lebih baik?
Yang merupakan cara yang disukai untuk mengubah Enum ke String di. NET 3.5?
Mengapa saya harus memilih salah satu dari ini daripada yang lain? Apakah seseorang berkinerja lebih baik?
Jawaban:
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.
nameof(variableEnum)akan terjadi "variableEnum". Ini mencerminkan (saat membangun) nama bidang / properti / param / variabel bukan nilai .
"someEnumValue", sementara Anda harus nameof(SomeEnum.FooBar)mendapatkannya "FooBar".
Bekerja untuk proyek kami ...
public static String convertToString(this Enum eff)
{
return Enum.GetName(eff.GetType(), eff);
}
public static EnumType converToEnum<EnumType>(this String enumValue)
{
return (EnumType) Enum.Parse(typeof(EnumType), enumValue);
}
Dalam pengujian saya, Enum.GetNamelebih cepat dan dengan margin yang layak. ToStringPanggilan internal Enum.GetName. Dari sumber untuk .NET 4.0, yang penting:
public override String ToString()
{
return Enum.InternalFormat((RuntimeType)GetType(), GetValue());
}
private static String InternalFormat(RuntimeType eT, Object value)
{
if (!eT.IsDefined(typeof(System.FlagsAttribute), false))
{
String retval = GetName(eT, value); //<== the one
if (retval == null)
return value.ToString();
else
return retval;
}
else
{
return InternalFlagsFormat(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.
Setup tes : enum dengan 8 nilai, no. iterasi = 1000000
Hasil : Enum.GetName => 700 ms, ToString => 2000 ms
Jika kecepatan tidak terlihat, saya tidak akan peduli dan menggunakannya ToStringkarena menawarkan panggilan yang jauh lebih bersih. Kontras
Enum.GetName(typeof(Bla), value)
dengan
value.ToString()
Ini adalah metode paling elegan yang dimaksudkan untuk itu.
var enumValueString = Enum.GetName(typeof (MyEnum), MyEnum.MyValue);
Meskipun saya tidak melihat masalah dengan panggilan .ToString()karena itu hanya lebih pendek.
var enumValueString = MyEnum.MyValue.ToString();
Dengan sintaks C # 6 baru Anda dapat menggunakan:
nameof(MyEnum.MyValue)
Semua ini secara internal akhirnya memanggil metode yang disebut InternalGetValueAsString. Perbedaan antara ToStringdan GetNameyang GetNameharus memverifikasi beberapa hal pertama:
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.
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 ,
Melewati enum kotak ke string.Format () atau fungsi lainnya dapat mengakibatkan
enum.ToString()dipanggil. Ini akan menyebabkan masalah saat Dotfuscating. Anda tidak harus menggunakanenum.ToString(),enum.GetNames(),enum.GetName(),enum.Format()atauenum.Parse()untuk mengkonversi enum ke string. Alih-alih, gunakan pernyataan peralihan, dan internasionalkan nama jika perlu.
Enum.GetName()
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:
Enum.GetName: ~ 800ms
.ToString (): ~ 1600ms
Kamus pemetaan: ~ 250ms