Saya ingin membuat metode umum untuk mengonversi tipe turunan System.Enum apa pun ke nilai integer yang sesuai, tanpa casting dan sebaiknya tanpa parsing string.
Misalnya, yang saya inginkan adalah seperti ini:
// Trivial example, not actually what I'm doing.
class Converter
{
int ToInteger(System.Enum anEnum)
{
(int)anEnum;
}
}
Tapi ini sepertinya tidak berhasil. Resharper melaporkan bahwa Anda tidak dapat menggunakan ekspresi tipe 'System.Enum' untuk mengetik 'int'.
Sekarang saya telah menemukan solusi ini tetapi saya lebih memilih sesuatu yang lebih efisien.
class Converter
{
int ToInteger(System.Enum anEnum)
{
return int.Parse(anEnum.ToString("d"));
}
}
Ada saran?
c#
enums
type-conversion
orj
sumber
sumber
Jawaban:
Jika Anda tidak ingin melakukan cast,
bisa melakukan triknya.
Pemeran langsung (melalui
(int)enumValue
) tidak dimungkinkan. Catatan bahwa ini juga akan menjadi "berbahaya" karena enum dapat memiliki jenis yang mendasari yang berbeda (int
,long
,byte
...).Secara lebih formal:
System.Enum
tidak memiliki hubungan pewarisan langsung denganInt32
(meskipun keduanya adalahValueType
), jadi pemeran eksplisit tidak dapat benar dalam sistem tipesumber
Converter.ToInteger(MyEnum.MyEnumConstant);
tidak akan memberi Anda kesalahan di sini. Harap edit bagian itu.int
long
enum.System.Enum
adalah kelas, jadi ini adalah tipe referensi. Nilai mungkin dikotakkan.Saya membuatnya bekerja dengan mentransmisikan ke objek dan kemudian ke int:
Ini jelek dan mungkin bukan cara terbaik. Saya akan terus mengotak-atiknya, untuk melihat apakah saya bisa menghasilkan sesuatu yang lebih baik ....
EDIT: Baru saja akan memposting bahwa Convert.ToInt32 (enumValue) berfungsi juga, dan perhatikan bahwa MartinStettner mengalahkan saya untuk itu.
Uji:
EDIT 2: Di komentar, seseorang mengatakan bahwa ini hanya berfungsi di C # 3.0. Saya baru saja menguji ini di VS2005 seperti ini dan berhasil:
sumber
Jika Anda perlu mengonversi enum apa pun ke tipe dasarnya (tidak semua enum didukung oleh
int
), Anda dapat menggunakan:sumber
Convert.ChangeType
menerimaobject
argumen pertama, dan kembaliobject
.Mengapa Anda perlu menemukan kembali roda dengan metode helper? Sangat legal untuk memberikan
enum
nilai pada tipe dasarnya.Ini kurang mengetik, dan menurut saya lebih mudah dibaca, menggunakan ...
... daripada sesuatu seperti ...
sumber
Dari jawaban saya di sini :
Diberikan
e
seperti pada:Kemudian pekerjaan ini:
Dua yang terakhir sangat jelek. Yang pertama harus lebih mudah dibaca, meskipun yang kedua lebih cepat. Atau mungkin metode penyuluhan adalah yang terbaik, terbaik dari kedua dunia.
Sekarang Anda dapat menghubungi:
sumber
e
variabel sudah memiliki contoh kotak dari tipe nilai aktual, yaitu enum. Saat Anda menulisEnum e = Question.Role;
itu sudah kotak. Pertanyaannya adalah tentang mengubah kotakSystem.Enum
kembali ke tipe int yang mendasari (unboxing). Jadi di sini unboxing hanyalah masalah kinerja.(int)(object)e
adalah panggilan unbox langsung; ya harus lebih cepat dari pendekatan lain. Lihat iniMentransmisi dari a
System.Enum
ke anint
berfungsi dengan baik untuk saya (juga ada di MSDN ). Mungkin itu bug Resharper.sumber
System.Enum
, bukanSystem.Enum
dirinya sendiri.Karena Enum dibatasi untuk byte, sbyte, short, ushort, int, uint, long dan ulong, kita dapat membuat beberapa asumsi.
Kami dapat menghindari pengecualian selama konversi dengan menggunakan wadah terbesar yang tersedia. Sayangnya, wadah mana yang akan digunakan tidak jelas karena ulong akan meledak untuk angka negatif dan panjang akan meledak untuk angka antara long.MaxValue dan ulong.MaxValue. Kita perlu beralih di antara pilihan ini berdasarkan jenis yang mendasarinya.
Tentu saja, Anda masih perlu memutuskan apa yang harus dilakukan jika hasilnya tidak sesuai dengan int. Saya pikir casting tidak apa-apa, tetapi masih ada beberapa kekurangan:
Inilah saran saya, saya akan menyerahkannya kepada pembaca untuk memutuskan di mana akan mengekspos fungsi ini; sebagai pembantu atau perpanjangan tangan.
sumber
Jangan lupa bahwa tipe Enum itu sendiri memiliki banyak fungsi pembantu statis di dalamnya. Jika semua yang ingin Anda lakukan adalah mengonversi instance enum ke jenis bilangan bulat yang sesuai, maka transmisi mungkin adalah cara yang paling efisien.
Saya pikir ReSharper mengeluh karena Enum bukanlah pencacahan jenis tertentu, dan pencacahan itu sendiri berasal dari jenis penilaian skalar, bukan Enum. Jika Anda memerlukan casting yang dapat disesuaikan dengan cara yang umum, saya akan mengatakan ini dapat menyesuaikan Anda dengan baik (perhatikan bahwa jenis enumerasi itu sendiri juga termasuk dalam generik:
Ini kemudian dapat digunakan seperti ini:
Saya tidak bisa mengatakan dengan pasti dari atas kepala saya, tetapi kode di atas bahkan mungkin didukung oleh inferensi tipe C #, memungkinkan yang berikut:
sumber
EnumHelpers.Convert<int, StopLight>(StopLight.Red);
daripada(int)StopLight.Read;
? Juga pertanyaan yang sedang dibicarakanSystem.Enum
.