C# – Flags Attribute’u İle Toplu Enumeration Tanımlama
Merhaba,
Enumeration, yapısı gereği bir veya birden fazla değeri numaralandırmak ve bu atanan numaralar üzerinden işlem yapmak için kullanılan bir araçtır. Kullanım olarak birçok varyasyonu bulunsada bunlar arasında amaçsal olarak diğerlerinden farklılık göstermeyen lakin işlevsel olarak oldukça farklı nimetler sunan bir özelliği mevcuttur. “Flags” özelliği… Enumaration’lara “Flags” attribute’u ile kazandırılan bu özellik sayesinde ilgili enumeration sayısal bir işlevsellik olan numaralandırıcı özelliğinden çıkarak, toplu numaralandırıcı özelliği gösteren farklı bir tipe bürünebilmekte ve sayısal değil koleksiyonel bir nitelik arz etmektedir. Şimdi gelin bu içeriğimizde Flags Attribute’u ile enumerationlar üzerinde nasıl bir değişiklik yapıldığını detaylıca inceleyelim.
İlk olarak aşağıdaki tanımlanmış enumerationı ele alalım;
public enum Yetkiler
{
Ekle = 1,
Sil = 2,
Guncelle = 4,
Listele = 8
}
Dikkat ederseniz eğer her bir maddeye numara olarak iki ve ikinin katları verilmiştir. Bunun nedenini merak ederseniz eğer aşağıdaki kullanım tarzını inceleyiniz;
Console.WriteLine(Yetkiler.Ekle | Yetkiler.Sil); //3
Console.WriteLine(Yetkiler.Listele | Yetkiler.Guncelle); //12
Console.WriteLine(Yetkiler.Guncelle | Yetkiler.Sil); //6
Console.WriteLine(Yetkiler.Ekle | Yetkiler.Guncelle); //5
Eğer ki, enumeration üzerinde “|” operatörü ile işlem yaparsak her iki maddenin sayısal değerleri üzerinde bir toplama işlemi yapacaktır. Dolayısıyla elde edilecek sonucun hangi değerlerin toplamını verdiğini anlayabilmek için herhangi iki değerin toplam sonucu bir üçüncü değerin sayısal değerinden farklı olması gerekmektedir. İşte bu ihtiyaca dönük tek ve garanti çözüm enumeration değerlerini iki ve ikinin katı olarak vermekten geçer…
Peki hoca, bu toplam sonuçlarının hangi değerlere karşılık geldiğini nereden bileceğiz? diye sorduğunuzu duyar gibiyim… Yani diyorsunuz ki; “3” değerini elde ediyorsam bunun “Ekle” ile “Sil” olduğunu nereden anlayacağız…
Aslında bu sorunun iki farklı cevabı var diyebilirim. Birincisi; mevcut toplamı oluşturabilecek sayısal değerleri birşekilde tahmin etmekten geçmektedir ki bu hem zor hemde lüzumsuz yere bir maliyet gerektirmektedir. İkincisi ise; asıl konumuz olan ve basit ama oldukça etkili yöntem diyebileceğimiz Flags attribute’unu kullanmaktır. Tabi ki de biz bu içeriğimizde birinci yönteme zerre kadar değinmeden direkt olarak ikinci yöntemi ele almaya başlayacağız.
[Flags]
public enum Yetkiler
{
Ekle = 1,
Sil = 2,
Guncelle = 4,
Listele = 8
}
Yukarıdaki kod bloğunu incelerseniz eğer enumerationımızı Flags attributeu ile işaretlemiş bulunmaktayız. Hal böyleyken yine makalemizin önceki satırlarında kullandığımız yöntemi tekrar tecrübe edersek eğer;
Console.WriteLine(Yetkiler.Ekle | Yetkiler.Sil); //Ekle, Sil
Console.WriteLine(Yetkiler.Listele | Yetkiler.Guncelle); //Listele, Guncelle
Console.WriteLine(Yetkiler.Guncelle | Yetkiler.Sil); //Guncelle, Sil
Console.WriteLine(Yetkiler.Ekle | Yetkiler.Guncelle); //Ekle, Guncelle
görüldüğü üzere bu sefer toplam sonuçları nihayi sonuca denk gelebilecek olan maddeleri direkt olarak bizlere getirmektedir.
Harika değil mi?
Bu şekilde bir nesneye, alana, değişkene yahut kullanıcıya birden fazla değeri verebiliriz ve bunu tek bir enumeration üzerinden gerçekleştiriyor olabiliriz…
Peki hoca, elde edilen bu sonucu elimizdeki mevcut enumeration değerleriyle nasıl kıyaslayacağız? sorunuza karşılık ise aşağıdaki kod bloğu yeterince tatmin edici bir cevap olacaktır…
Yetkiler yetki = Yetkiler.Ekle | Yetkiler.Listele;
Console.WriteLine(yetki.HasFlag(Yetkiler.Ekle)); //True
Console.WriteLine(yetki.HasFlag(Yetkiler.Sil)); //False
Console.WriteLine(yetki.HasFlag(Yetkiler.Listele)); //True
Console.WriteLine(yetki.HasFlag(Yetkiler.Guncelle)); //False
Görüldüğü üzere “HasFlag” metodu sayesinde hangi değerlerin girildiğini kıyaslayarak öğrenebilmekteyiz.
İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Merhaba, düzeltilmesi gereken iki ifade tespit ettim. Birincisi enumerationın değerlerini “2 ve 2’nin katı olacak şekilde yazılmalı” ifadesi yerine “2’nin üsleri şeklinde yazılmalı” olarak değiştirilmelidir. Çünkü 6 da 2’nin katıdır, 10 da 2’nin katıdır. Bunlar yazılırsa sistem çalışmaz. (10 OR 2 = 14 eder) Diğer değişmesi gereken ifade ise yalnızca 2nin üsleri şeklinde yazılan sayısal ifadeler OR işlemine tabi tutulursa sayısal olarak toplam sonucunu verir. Makaledeki ifadede herhangi 2 tabanına göre 2 tam sayı operandı OR işlemine tabi tutarsak toplama işlemi yapılır gibi anlaşılıyor. Enum değerlerini 0,1,2,4,8,16,32 olcak şekilde arttırırsanız ve üslü ifade ederseniz hatalı anlaşılmanın önüne geçilir. İyi çalışmalar dilerim.
Evet, uyarı için teşekkür ederim. Yoruma istinaden ilgili alanları ilerideki süreçte düzenlemiş olacağım.
İyi çalışmalar.