Saya memiliki bendera enum di bawah ini.
[Flags]
public enum FlagTest
{
None = 0x0,
Flag1 = 0x1,
Flag2 = 0x2,
Flag3 = 0x4
}
Saya tidak bisa membuat pernyataan if mengevaluasi ke true.
FlagTest testItem = FlagTest.Flag1 | FlagTest.Flag2;
if (testItem == FlagTest.Flag1)
{
// Do something,
// however This is never true.
}
Bagaimana saya bisa mewujudkannya?
None
bendera dengan nilai nol. Lihat msdn.microsoft.com/en-us/library/vstudio/…&
Operator untuk perbandingan,|
seperti tambahan:1|2=3
,5|2=7
,3&2=2
,7&2=2
,8&2=0
.0
mengevaluasi untukfalse
, semua yang lainnyatrue
.Jawaban:
Di .NET 4 ada metode baru Enum.HasFlag . Ini memungkinkan Anda untuk menulis:
yang jauh lebih mudah dibaca, IMO.
Sumber .NET menunjukkan bahwa ini melakukan logika yang sama dengan jawaban yang diterima:
sumber
Enum
kelas.(testItem & FlagTest.Flag1)
adalah operasi DAN bitwise.FlagTest.Flag1
setara dengan001
dengan enum OP. Sekarang katakanlahtestItem
memiliki Flag1 dan Flag2 (jadi bitwise101
):sumber
Bagi mereka yang kesulitan memvisualisasikan apa yang terjadi dengan solusi yang diterima (yang ini),
testItem
(sesuai pertanyaan) didefinisikan sebagai,Kemudian, dalam pernyataan if, sisi kiri perbandingan adalah,
Dan pernyataan if penuh (yang mengevaluasi true jika
flag1
diatur dalamtestItem
),sumber
@ phil-devaney
Perhatikan bahwa kecuali dalam kasus yang paling sederhana, Enum.HasFlag membawa penalti performa yang berat dibandingkan dengan menuliskan kode secara manual. Pertimbangkan kode berikut:
Lebih dari 10 juta iterasi, metode ekstensi HasFlags mengambil 4793 ms kekalahan, dibandingkan dengan 27 ms untuk implementasi bitwise standar.
sumber
(«flag var» & «flag value») != 0
tidak bekerja untuk saya. Kondisi selalu gagal dan kompiler saya (Unity3D's Mono 2.6.5) melaporkan "peringatan CS0162: Kode yang tidak terjangkau terdeteksi" ketika digunakan dalam sebuahif (…)
.… = 1, … = 2, … = 4
pada nilai enum sangat penting saat digunakan[Flags]
. Saya berasumsi bahwa itu akan memulai entri1
dan maju dengan Po2s secara otomatis. Perilaku terlihat konsisten di seluruh MS .NET dan Mono tanggal Unity. Maafkan saya yang menempatkan ini pada Anda.Saya menyiapkan metode ekstensi untuk melakukannya: pertanyaan terkait .
Pada dasarnya:
Maka Anda dapat melakukan:
Kebetulan konvensi yang saya gunakan untuk enums adalah singular untuk standar, jamak untuk bendera. Dengan begitu Anda tahu dari nama enum apakah itu bisa menampung beberapa nilai.
sumber
HasFlag
ekstensi sebagai gantinya.Satu saran lagi ... Jangan pernah melakukan pemeriksaan biner standar dengan flag yang nilainya "0". Cek Anda pada bendera ini akan selalu benar.
Jika Anda biner memeriksa parameter input terhadap FullInfo - Anda mendapatkan:
bPRez akan selalu benar karena APA SAJA & 0 selalu == 0.
Sebagai gantinya, Anda cukup memeriksa bahwa nilai input adalah 0:
sumber
sumber
Untuk operasi bit, Anda perlu menggunakan operator bitwise.
Ini harus melakukan trik:
Sunting: Memperbaiki cek saya jika - Saya kembali ke C / C ++ cara saya (terima kasih kepada Ryan Farley untuk menunjukkannya)
sumber
Mengenai hasil edit. Anda tidak bisa mewujudkannya. Saya sarankan Anda membungkus apa yang Anda inginkan ke kelas lain (atau metode ekstensi) untuk lebih dekat dengan sintaks yang Anda butuhkan.
yaitu
sumber
Coba ini:
Pada dasarnya, kode Anda menanyakan apakah kedua set flag sama dengan satu set flag, yang jelas salah. Kode di atas hanya akan menyisakan bit Flag1 jika diset sama sekali, lalu membandingkan hasil ini dengan Flag1.sumber
bahkan tanpa [Bendera], kamu bisa menggunakan sesuatu seperti ini
atau jika Anda memiliki nilai nol enum
sumber