Enum biasa menampung satu pilihan pada satu waktu: sebuah pesanan berstatus Dikirim, bukan Dikirim sekaligus Dibayar. Kebutuhan lain muncul ketika satu objek boleh memiliki banyak pilihan bersamaan, misalnya izin akses berupa baca, tulis, dan hapus sekaligus. Atribut [Flags] memberi tahu compiler bahwa anggota enum dimaksudkan untuk digabung secara bitwise, sehingga satu nilai enum dapat menyimpan banyak pilihan sekaligus.
Menggabungkan dan Menguji Izin #
Contoh berikut mendefinisikan flags enum IzinAkses, menggabungkan izin, mengujinya, lalu mencabut salah satunya:
[Flags]
public enum IzinAkses { None = 0, Baca = 1, Tulis = 2, Hapus = 4 }
IzinAkses izinEditor = IzinAkses.Baca | IzinAkses.Tulis;
Console.WriteLine(izinEditor);
Console.WriteLine((int)izinEditor);
Console.WriteLine(izinEditor.HasFlag(IzinAkses.Baca));
Console.WriteLine(izinEditor.HasFlag(IzinAkses.Hapus));
IzinAkses izinSetelahDicabut = izinEditor & ~IzinAkses.Tulis;
Console.WriteLine(izinSetelahDicabut);
IzinAkses izinPenuh = IzinAkses.Baca | IzinAkses.Tulis | IzinAkses.Hapus;
Console.WriteLine(izinPenuh);Output yang Dihasilkan:
Baca, Tulis
3
True
False
Baca
Baca, Tulis, HapusMari kita bedah baris demi baris:
[Flags]: atribut ini memengaruhi formatToString; tanpa atribut, nilai gabungan3hanya tampil sebagai angka, bukan daftar nama.IzinAkses.Baca | IzinAkses.Tulis: operator bitwise|menggabungkan bit1dan bit2menjadi nilai3yang memuat dua izin sekaligus.izinEditor.HasFlag(IzinAkses.Baca): methodHasFlagmenguji satu pilihan di dalam nilai gabungan; hasilnyaTrueuntukBacadanFalseuntukHapus.izinEditor & ~IzinAkses.Tulis: operator&bersama komplemen~mematikan bitTulistanpa menyentuh bit lain; hasilnya tinggalBaca.izinPenuh: gabungan tiga izin bernilai7dan tampil sebagai daftar namaBaca, Tulis, Hapus.
Menambahkan Pilihan ke Variable yang Ada #
Operator gabungan-ke |= menambahkan satu pilihan ke variable flags enum tanpa menghapus pilihan lain. Contoh berikut membangun izin tamu mulai dari None:
IzinAkses izinTamu = IzinAkses.None;
izinTamu |= IzinAkses.Baca;
izinTamu |= IzinAkses.Hapus;
Console.WriteLine(izinTamu);
Console.WriteLine(izinTamu.HasFlag(IzinAkses.Tulis));Output yang Dihasilkan:
Baca, Hapus
FalseVariable izinTamu dimulai dari None, lalu |= menambahkan bit Baca dan bit Hapus satu per satu; hasilnya tampil sebagai Baca, Hapus. Penguji HasFlag menegaskan Tulis tidak ikut menyala, sehingga penambahan bit tidak menimpa pilihan yang sudah ada.
Aturan Penomoran Anggota #
Flags enum menuntut anggota bernilai pangkat dua: 1, 2, 4, 8, 16, dan seterusnya, karena setiap anggota menempati satu bit sendiri. Sertakan anggota None = 0 sebagai nilai awal yang tidak memiliki pilihan apa pun. Bila dua anggota berbagi bit yang sama, pengujian HasFlag tidak dapat membedakan keduanya lagi. Perlu diingat bahwa atribut [Flags] tidak mengubah cara bit disimpan; atribut hanya mengubah tampilan nilai gabungan agar terbaca sebagai daftar nama.