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:

csharp
[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:

text
Baca, Tulis
3
True
False
Baca
Baca, Tulis, Hapus

Mari kita bedah baris demi baris:

  1. [Flags]: atribut ini memengaruhi format ToString; tanpa atribut, nilai gabungan 3 hanya tampil sebagai angka, bukan daftar nama.
  2. IzinAkses.Baca | IzinAkses.Tulis: operator bitwise | menggabungkan bit 1 dan bit 2 menjadi nilai 3 yang memuat dua izin sekaligus.
  3. izinEditor.HasFlag(IzinAkses.Baca): method HasFlag menguji satu pilihan di dalam nilai gabungan; hasilnya True untuk Baca dan False untuk Hapus.
  4. izinEditor & ~IzinAkses.Tulis: operator & bersama komplemen ~ mematikan bit Tulis tanpa menyentuh bit lain; hasilnya tinggal Baca.
  5. izinPenuh: gabungan tiga izin bernilai 7 dan tampil sebagai daftar nama Baca, 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:

csharp
IzinAkses izinTamu = IzinAkses.None;
izinTamu |= IzinAkses.Baca;
izinTamu |= IzinAkses.Hapus;

Console.WriteLine(izinTamu);
Console.WriteLine(izinTamu.HasFlag(IzinAkses.Tulis));

Output yang Dihasilkan:

text
Baca, Hapus
False

Variable 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.