Dari waktu ke waktu saya melihat enum seperti berikut:
[Flags]
public enum Options
{
None = 0,
Option1 = 1,
Option2 = 2,
Option3 = 4,
Option4 = 8
}
Saya tidak mengerti apa sebenarnya [Flags]
atribut tersebut.
Adakah yang punya penjelasan atau contoh bagus yang bisa mereka posting?
CatAndDog = Cat | Dog
(logika ATAU bukannya Bersyarat), saya kira?Jawaban:
The
[Flags]
atribut harus digunakan setiap kali enumerable merupakan kumpulan nilai yang mungkin, bukan nilai tunggal. Koleksi semacam itu sering digunakan dengan operator bitwise, misalnya:Perhatikan bahwa
[Flags]
atribut tidak mengaktifkan ini dengan sendirinya - semua yang dilakukannya adalah memperbolehkan representasi yang bagus dengan.ToString()
metode:Penting juga untuk dicatat bahwa
[Flags]
tidak secara otomatis membuat enum nilai kekuatan dua. Jika Anda menghilangkan nilai numerik, enum tidak akan berfungsi seperti yang diharapkan dalam operasi bitwise, karena secara default nilai dimulai dengan 0 dan kenaikan.Deklarasi salah:
Nilai-nilai, jika dinyatakan dengan cara ini, akan menjadi Kuning = 0, Hijau = 1, Merah = 2, Biru = 3. Ini akan menjadikannya tidak berguna sebagai bendera.
Berikut ini contoh deklarasi yang benar:
Untuk mengambil nilai berbeda di properti Anda, orang dapat melakukan ini:
atau sebelum .NET 4:
Di bawah selimut
Ini berfungsi karena Anda menggunakan kekuatan dua dalam enumerasi Anda. Di bawah sampul, nilai enumerasi Anda terlihat seperti ini dalam nilai biner dan nol:
Demikian pula, setelah Anda mengatur properti Anda AllowColors ke Merah, Hijau dan Biru menggunakan bitwise biner ATAU
|
operator, DiizinkanColors terlihat seperti ini:Jadi ketika Anda mengambil nilai Anda sebenarnya melakukan bitwise DAN
&
pada nilai-nilai:Nilai None = 0
Dan mengenai penggunaan
0
dalam enumerasi Anda, mengutip dari MSDN:Anda dapat menemukan lebih banyak info tentang atribut flags dan penggunaannya di msdn dan mendesain flags di msdn
sumber
ToString
pelaksanaan enum Anda menggunakan Flags, dan begitu jugaEnum.IsDefined
,Enum.Parse
, dll Cobalah untuk menghapus Flags dan melihat hasil MyColor.Yellow | MyColor.Red; tanpa itu Anda mendapatkan "5", dengan Bendera Anda mendapatkan "Kuning, Merah". Beberapa bagian lain dari kerangka kerja ini juga menggunakan [Flags] (misalnya, Serialisasi XML).myProperties.AllowedColors = MyColor.Red | MyColor.Green | MyColor.Blue;
. Anda dapat melakukan:myProperties.AllowedColors = myProperties.AllowedColors ^ MyColor.Blue //myProperties.AllowedColors == MyColor.Red | Mycolor.Green
Anda juga bisa melakukan ini
Saya menemukan bit-shifting lebih mudah daripada mengetik 4,8,16,32 dan seterusnya. Itu tidak berdampak pada kode Anda karena semuanya dilakukan pada waktu kompilasi
sumber
Third = Second << 1
daripadaThird = 1 << 2
- lihat deskripsi lebih lengkap di bawah ini1 << 31 == -2147483648
,1 << 32 == 1
,1 << 33 == 2
, dan sebagainya. Sebaliknya, jika Anda mengatakanThirtySecond = 2147483648
untuk tipe int enum, kompiler melempar kesalahan.Menggabungkan jawaban https://stackoverflow.com/a/8462/1037948 (deklarasi melalui bit-shifting) dan https://stackoverflow.com/a/9117/1037948 (menggunakan kombinasi dalam deklarasi) Anda dapat menggeser-geser nilai sebelumnya sebagai gantinya daripada menggunakan angka. Tidak perlu merekomendasikannya, tetapi hanya menunjukkan Anda bisa.
Daripada:
Anda bisa mendeklarasikan
Mengkonfirmasi dengan LinqPad:
Hasil dalam:
sumber
Silakan lihat berikut ini untuk contoh yang menunjukkan deklarasi dan potensi penggunaan:
sumber
Sebagai perpanjangan dari jawaban yang diterima, di C # 7 bendera enum dapat ditulis menggunakan literal biner:
Saya pikir representasi ini memperjelas bagaimana bendera bekerja di bawah selimut .
sumber
0b_0100
Saya bertanya baru - baru ini tentang sesuatu yang serupa.
Jika Anda menggunakan flag, Anda dapat menambahkan metode ekstensi ke enum untuk mempermudah memeriksa flag yang ada (lihat posting untuk detail)
Ini memungkinkan Anda untuk melakukan:
Maka Anda dapat melakukan:
Saya menemukan ini lebih mudah dibaca daripada kebanyakan cara memeriksa bendera yang disertakan.
sumber
HasFlag
metode untuk enumerasi, sehingga Anda dapat melakukannyaopt.HasFlag( PossibleOptions.OptionOne )
tanpa harus menulis ekstensi Anda sendiriHasFlag
ini jauh lebih lambat daripada melakukan operasi bitwise.@Nidonocu
Untuk menambahkan flag lain ke set nilai yang ada, gunakan operator penugasan ATAU.
sumber
Ketika bekerja dengan bendera, saya sering menyatakan Tidak Ada dan Semua item tambahan. Ini sangat membantu untuk memeriksa apakah semua flag diatur atau tidak ada flag yang ditetapkan.
Pemakaian:
Pembaruan 2019-10:
Karena C # 7.0 Anda dapat menggunakan literal biner, yang mungkin lebih intuitif untuk dibaca:
sumber
Untuk menambahkan
Mode.Write
:sumber
Ada sesuatu yang terlalu verbose kepada saya tentang
if ((x & y) == y)...
membangun, terutama jikax
DANy
keduanya set senyawa bendera dan Anda hanya ingin tahu apakah ada setiap tumpang tindih.Dalam hal ini, yang benar-benar perlu Anda ketahui adalah jika ada nilai non-nol [1] setelah Anda bitmasked .
Membangun dari penyiapan @ andnil ...
sumber
enum
, kami harus memeriksanya!= 0
.Bendera memungkinkan Anda untuk menggunakan bitmasking di dalam enumerasi Anda. Ini memungkinkan Anda untuk menggabungkan nilai enumerasi, sambil mempertahankan yang ditentukan.
sumber
Mohon maaf jika seseorang sudah memperhatikan skenario ini. Contoh sempurna dari bendera yang dapat kita lihat dalam refleksi. Ya Mengikat Bendera ENUM. https://docs.microsoft.com/en-us/dotnet/api/system.reflection.bindingflags?view=netframework-4.8
Pemakaian
sumber