jawaban singkatnya, ya. Dalam kasus khusus ini, Anda mungkin ingin mempertimbangkan penggunaanTimeSpan
Jodrell
1
Menggunakan metode ekstensi pada enum akan membuat saya merasa kotor. Buat kelas untuk merangkum apa yang dibutuhkan. Buat enum sesederhana mungkin. Jika Anda memerlukan lebih banyak logika yang terkait dengannya, buat kelas Durasi yang memperlihatkan hari, minggu, bulan plus berisi logika lain yang mungkin ada dalam metode ekstensi.
Jason Evans
2
Saya suka memiliki metode ekstensi enum untuk grup bendera. Saya lebih suka kalau klausa misalnya Day.IsWorkday()lebih (Day & Days.Workday) > 0dengan Days.Workdaydidefinisikan sebagai Monday | Tuesday ... | Friday. Yang pertama lebih jelas menurut saya dan justru yang terakhir diimplementasikan.
Metode ekstensi menyediakan cara untuk menulis metode untuk kelas yang ada dengan cara yang mungkin ditemukan dan digunakan oleh orang lain di tim Anda. Mengingat bahwa enum adalah kelas seperti yang lain, seharusnya tidak terlalu mengejutkan jika Anda dapat memperluasnya, seperti:
Saya pikir enum bukanlah pilihan terbaik secara umum tetapi setidaknya ini memungkinkan Anda memusatkan beberapa sakelar / jika menangani dan mengabstraksi mereka sedikit sampai Anda dapat melakukan sesuatu yang lebih baik. Ingatlah untuk memeriksa bahwa nilainya juga dalam kisaran.
Anda dapat membaca lebih lanjut di sini di Microsft MSDN.
Saya percaya komentar "enum is evil" tidak pada tempatnya tetapi memiliki dasar dalam kenyataan. Saya menemukan bahwa enum bisa menjadi masalah jika digunakan secara berlebihan, karena enum semacam mengunci Anda dalam konteks dan perilaku tertentu.
Ed Schwehm
1
Enums di C # jenis payah karena ini mengkompilasi dan berjalan:Duration d = 0;
Graham
16
Given that enums are classestidak, mereka bukan kelas.
Pemain sayap Sendon
1
Saya menggunakan ekstensi semacam ini hanya jika itu tentang enum secara langsung, seperti hari dalam seminggu dan metode ekstensi IsWeekday (), IsWeekendday (). Tetapi kelas dimaksudkan untuk merangkum perilaku, jadi jika ada banyak atau perilaku rumit untuk diringkas, kelas mungkin lebih baik. Jika terbatas dan dasar, saya pribadi menemukan ekstensi pada enum oke. Seperti kebanyakan keputusan desain, ada batasan fuzzy antara pilihan (IMO). Perlu dicatat bahwa ekstensi hanya dapat dilakukan pada kelas statis tingkat atas, bukan kelas bersarang. Jika enum Anda adalah bagian dari kelas, Anda harus membuat kelas.
FreeText
51
Anda juga dapat menambahkan metode ekstensi ke tipe Enum daripada contoh Enum:
/// <summary> Enum Extension Methods </summary>/// <typeparam name="T"> type of Enum </typeparam>publicclassEnum<T>where T :struct,IConvertible{publicstaticintCount{get{if(!typeof(T).IsEnum)thrownewArgumentException("T must be an enumerated type");returnEnum.GetNames(typeof(T)).Length;}}}
Anda dapat menjalankan metode ekstensi di atas dengan melakukan:
var result =Enum<Duration>.Count;
Ini bukan metode ekstensi yang sebenarnya. Ini hanya berfungsi karena Enum <> adalah tipe yang berbeda dari System.Enum.
Bisakah kelas staticmemastikan semua metodenya berperilaku seperti ekstensi?
Jatin Sanghvi
15
Bagi pembaca yang akan datang: ambiguitas nama Enum<T>agak membingungkan. Kelas juga bisa dipanggil EnumUtils<T>dan pemanggilan metode akan diselesaikan menjadi EnumUtils<Duration>.Count.
Namoshek
46
Tentu saja Anda dapat, katakanlah misalnya, Anda ingin menggunakan DescriptionAttribuepada enumnilai Anda :
using System.ComponentModel.DataAnnotations;publicenumDuration{[Description("Eight hours")]Day,[Description("Five days")]Week,[Description("Twenty-one days")]Month}
Sekarang Anda ingin dapat melakukan sesuatu seperti:
Duration duration =Duration.Week;var description = duration.GetDescription();// will return "Five days"
Metode ekstensi Anda GetDescription()dapat ditulis sebagai berikut:
using System.ComponentModel;
using System.Reflection;publicstaticstringGetDescription(thisEnumvalue){FieldInfo fieldInfo =value.GetType().GetField(value.ToString());if(fieldInfo ==null)returnnull;var attribute =(DescriptionAttribute)fieldInfo.GetCustomAttribute(typeof(DescriptionAttribute));return attribute.Description;}
saya sedang mencari untuk membuat ekstensi untuk hampir persis apa yang Anda sampel lakukan, kecuali saya menggunakan DisplayAttribute Localized GetDescription. bersulang
George
Ini adalah alternatif yang bagus, meskipun menurut saya namespace hanya System.ComponentModel?
TomDestry
Perspektif yang bagus dan terima kasih telah menunjukkan implementasi serta kode ekstensi. Untuk menambahkan: dengan implementasi Anda, Anda juga bisa menyebutnya seperti ini: var description = DurationWeek.GetDescription ();
Spencer Sullivan
31
Semua jawaban bagus, tetapi mereka berbicara tentang menambahkan metode ekstensi ke jenis enum tertentu.
Bagaimana jika Anda ingin menambahkan metode ke semua enum seperti mengembalikan int dari nilai saat ini alih-alih casting eksplisit?
publicstaticclassEnumExtensions{publicstaticintToInt<T>(this T soure)where T :IConvertible//enum{if(!typeof(T).IsEnum)thrownewArgumentException("T must be an enumerated type");return(int)(IConvertible) soure;}//ShawnFeatherly funtion (above answer) but as extention methodpublicstaticintCount<T>(this T soure)where T :IConvertible//enum{if(!typeof(T).IsEnum)thrownewArgumentException("T must be an enumerated type");returnEnum.GetNames(typeof(T)).Length;}}
Trik di belakangnya IConvertibleadalah lihat Hirarki Warisannya MDSN
Dito. Ini berfungsi jika saya memanggil ekstensi secara langsung (misalnya MyExtention.DoThing(myvalue)) tetapi tidak benar-benar melampirkan ke enum (misalnya myvalue.DoThing())
Sinaesthetic
1
FYI, C # 7.3 sekarang mendukung Enum sebagai batasan tipe generik
redtetrahedron
7
Anda dapat membuat ekstensi untuk apa pun, bahkan object(meskipun itu tidak dianggap sebagai praktik terbaik ). Pahami metode ekstensi hanya sebagai public staticmetode. Anda dapat menggunakan tipe parameter apa pun yang Anda suka pada metode.
Nilai voidkembali pada enum agak aneh. Saya akan memikirkan sampel yang lebih realistis.
psubsee2003
3
@ psubsee2003 OP pasti memiliki pengetahuan yang cukup untuk mengubah ini agar sesuai dengan kebutuhannya? Mengapa sampel itu penting, itu cukup untuk menjawab pertanyaan awal.
LukeHennerley
3
Apakah saya satu-satunya yang menganggap contoh kode di MSDN aneh? Sebagian besar waktu Anda membutuhkan upaya nyata untuk memahami apa yang mereka coba lakukan!
TimeSpan
Day.IsWorkday()
lebih(Day & Days.Workday) > 0
denganDays.Workday
didefinisikan sebagaiMonday | Tuesday ... | Friday
. Yang pertama lebih jelas menurut saya dan justru yang terakhir diimplementasikan.Jawaban:
Menurut situs ini :
Metode ekstensi menyediakan cara untuk menulis metode untuk kelas yang ada dengan cara yang mungkin ditemukan dan digunakan oleh orang lain di tim Anda. Mengingat bahwa enum adalah kelas seperti yang lain, seharusnya tidak terlalu mengejutkan jika Anda dapat memperluasnya, seperti:
Saya pikir enum bukanlah pilihan terbaik secara umum tetapi setidaknya ini memungkinkan Anda memusatkan beberapa sakelar / jika menangani dan mengabstraksi mereka sedikit sampai Anda dapat melakukan sesuatu yang lebih baik. Ingatlah untuk memeriksa bahwa nilainya juga dalam kisaran.
Anda dapat membaca lebih lanjut di sini di Microsft MSDN.
sumber
Duration d = 0;
Given that enums are classes
tidak, mereka bukan kelas.Anda juga dapat menambahkan metode ekstensi ke tipe Enum daripada contoh Enum:
Anda dapat menjalankan metode ekstensi di atas dengan melakukan:
Ini bukan metode ekstensi yang sebenarnya. Ini hanya berfungsi karena Enum <> adalah tipe yang berbeda dari System.Enum.
sumber
static
memastikan semua metodenya berperilaku seperti ekstensi?Enum<T>
agak membingungkan. Kelas juga bisa dipanggilEnumUtils<T>
dan pemanggilan metode akan diselesaikan menjadiEnumUtils<Duration>.Count
.Tentu saja Anda dapat, katakanlah misalnya, Anda ingin menggunakan
DescriptionAttribue
padaenum
nilai Anda :Sekarang Anda ingin dapat melakukan sesuatu seperti:
Metode ekstensi Anda
GetDescription()
dapat ditulis sebagai berikut:sumber
Semua jawaban bagus, tetapi mereka berbicara tentang menambahkan metode ekstensi ke jenis enum tertentu.
Bagaimana jika Anda ingin menambahkan metode ke semua enum seperti mengembalikan int dari nilai saat ini alih-alih casting eksplisit?
Trik di belakangnya
IConvertible
adalah lihat Hirarki Warisannya MDSNTerima kasih kepada ShawnFeatherly atas jawabannya
sumber
MyExtention.DoThing(myvalue)
) tetapi tidak benar-benar melampirkan ke enum (misalnyamyvalue.DoThing()
)Anda dapat membuat ekstensi untuk apa pun, bahkan
object
(meskipun itu tidak dianggap sebagai praktik terbaik ). Pahami metode ekstensi hanya sebagaipublic static
metode. Anda dapat menggunakan tipe parameter apa pun yang Anda suka pada metode.sumber
Lihat MSDN .
sumber
void
kembali pada enum agak aneh. Saya akan memikirkan sampel yang lebih realistis.kita baru saja membuat ekstensi enum untuk c # https://github.com/simonmau/enum_ext
Ini hanya implementasi untuk typesafeenum, tetapi berfungsi dengan baik sehingga kami membuat paket untuk dibagikan - bersenang-senanglah dengannya
Saya tahu contohnya agak tidak berguna, tetapi Anda mengerti;)
sumber
Solusi sederhana.
sumber