Memik Yanık - Kişisel Web Sitesi Ana Sayfa | Hakkımda | Kitap Önerileri | Fotoğraflarım | RSS RSS | İletişim

14. BÖLÜM : STRUCT ve ENUM TİPİ HAZIRLAMAK(*)


Struct yani yapılar Class’lara çok benzemektedir. Aralarındaki en önemli fark, bellekte tutuldukları yerdir. Class’lar belleğin Heap kısmında tutulan referans tür iken; yapılar değer türleri olup stack’te tutulmaktadır. Yapılar, tıpkı sınıflar gibi metotlar, yapıcı metotlar, sabitler, özellikler, alanlar içerebilirler. Struct’lar başka Struct’ın veya Class’ın mirasçısı olamaz. Ancak struct’lara interface’ler uygulanabilmektedir. Yapılar kalıtımı desteklemedikleri için abstract veya virtual olarak işaret edilemezler. Kısaca anlatmak gerekirse struct’ları bazı özellikleri kırpılmış Class’lar olarak ifade etmek mümkündür. 

Ne zaman class, ne zaman yapı hazırlanması gerektiği konusu tartışmaya açık olmakla birlikte struct’ın örneği bellekte fazla yer kaplamayacaksa struct’ı tercih edebilirsiniz. Aşağıda verilen uygulamada “adres” adında ve 3 alana sahip bir yapı tanımladık.



Bu struct’ı incelerseniz Class ile sınırlanan bloğun içine yazıldığını görebilirsiniz. Kodu okunur yapmak için struct; class tarafından sınırlanan bloktan çıkarılabilir. Yapıda yer alan alanlar istenen tipte olabilir. Bu şekilde tanımlanan yapıyı kullanabilmek için yapıdan yola çıkıp nesne hazırlamak gerekir. Bu işlemin nasıl yapıldığını aşağıda görebilirsiniz. 

namespace yapilar

  class sinif_1 
  
    public static void Main() 
    
       oyuncular nesne; 
       nesne = new oyuncular(); 
     
  
 struct oyuncular 
  
    public string ad; 
    public double boy; 
    public string takim; 
  }


Bu nesneyi Main() metodu içinde hazırladığımız için ancak bu metodun içinde kullanılabilir. Bu şekilde tanımlanan yapının elemanlarına istenildiği gibi bilgi aktarılabilinir. Tanımlanan yapının 3 elemanına aşağıda bilgi aktarılmaktadır.



Konunun iyice anlaşılmasını sağlamak için Visual Studio ile hazırladığımız projede bir yapı hazırlayıp kullanacağız. Bu kez hazırlayacağımız yapıyı başka class veya formlarda kullanabilmek için public yapacağız. Bildiğiniz gibi aynı namespace içinde istenilen sayıda Class olabilmektedir. Hazırladığınız Struct’ları mevcut kod dosyası içinde Class’lar ile bir arada tutabileceğiniz gibi başka bir CS dosyasına alabilirsiniz.



“oyuncular” adını verdiğimiz struct’ı bu şekilde tanımladıktan sonra bu yapıdan yola çıkarak “oyuncu” adında bir değişken tanımladık yani nesne hazırladık. Hem yapının elemanları public olduğundan hem de yapıdan türettiğimiz nesneyi static yaptığımız için diğer formlarda yapının elemanlarına nesne hazırlanmadan erişim sağlanabilir.



Struct tipindeki değişkenin elemanlarına bu şekilde bilgi aktardıktan sonra projedeki 2. forma geçip aşağıda verilen satırları yazdık. “nesne” adını vermiş olduğumuz değişken public olduğu için her form ve sınıfta kullanılabilir.



Struct’lar İçin Yapıcı Metot Hazırlamak 

Y
ukarıda belirtildiği gibi Struct’lar Class’lar gibi constructor(yapıcı) metotlara sahip olabilirler. Şimdi yukarıda hazırladığımız yapıyı biraz değiştirip constructor metoda sahip olmasını sağlayacağız. Bildiğiniz gibi constructor metotlar, sınıfların veya yapıların örnekleri alındığı zaman otomatik olarak işletilen ve struct ile aynı ada sahip metotlardır. Struct’ların yapıcı metotları Class’ların aksine parametreli olmak zorundadır. 

public struct oyuncular 
 
   public string ad; 
   public double boy; 
   public string takim; 
   public oyuncular(string Par1, double Par2, string Par3)
   
      this.ad = Par1; 
      this.boy = Par2; 
      this.takim = Par3; 
   
  

Bu şekilde düzenlenen yapının örneği hazırlandığında struct ile aynı ada sahip bu metot işletilir. Nesnenin örneği hazırlanırken parametreler kullanılmayabilir. Bu nedenle aşağıda verilen metot sorunsuz çalışır. 

private void Form1_Click(object sender, EventArgs e) 
 
   oyuncular nesne = new oyuncular(); 
   MessageBox.Show(nesne.ad);   
 

Struct için yapıcı metot hazırlanmamışsa alanlara ilk değer verme zorunluluğu vardır. new anahtar kelimesi kullanılmadan yapıların örneği alınabilir. Bu durumda yapının alanlarına ilk değer aktarılması gerekir. Yukarıda örnek olması için hazırladığımız struct 3 alana sahip olduğu ve dolayısıyla yapıcı metot 3 parametreye sahip olduğundan yapının örneği hazırlanırken parametre kullanılacaksa hepsi kullanılmalıdır. 

private void Form1_Click(object sender, EventArgs e)

  oyuncular nesne; 
  nesne = new oyuncular("Kerem Gönlüm", 2.10, "Efes Pilsen"); 
  textBox1.Text = nesne.ad; 
  textBox2.Text = Convert.ToString(nesne.boy); 
  textBox3.Text = nesne.takim;


Struct’ların yapıcı metotları Class’larınki gibi aşırı yüklenebilir veya değişik sayıda parametreye sahip versiyonları olabilir. Bu imkanı göstermek için yukarıda verilen yapıcı metodun 2 parametreli versiyonunu hazırlayıp kullandık. 

public struct oyuncular 
 
   public string ad; 
   public double boy; 
   public string takim; 
   public oyuncular(string Par1, double Par2, string Par3) 
   
      this.ad = Par1; 
      this.boy = Par2; 
      this.takim = Par3; 
   
   public oyuncular(string Par1, double Par2) 
    
        this.ad = Par1; 
        this.boy = Par2; 
        this.takim = ""; 
      
  

2 parametreli yapıcı metotta Struct’ın “takım” adını verdiğimiz 3. elemanına varsayılan değeri aktardık. String tipindeki 3. elemana bu şekilde boşluk aktarmasaydık hata meydana gelirdi. Diğer yandan Struct’lar için yok edici metot hazırlanamaz. 
Class’lar hakkında bilgi verilen bölümden hatırlayacağınız gibi .NET 2.0 ile birlikte Class’ların birden fazla parçaya bölünmesi, bir Class’a ait kodların birden fazla dosyada tutulmasına izin verilmeye başlandı. Birden fazla parçaya bölünmek istenen Class’ların partial olarak işaret edilmesi gerektiğini biliyorsunuz. Benzer şekilde Struct’ları partial olarak hazırlayıp birden fazla parçaya bölebilir veya kod dosyasına ayırabilirsiniz. Bu işlemin nasıl yapıldığını hatırlatmak için yukarıda verilen Struct’ı 2 parçaya böldük.



Yukarıda struct’ı önce Class’ın içinde hazırladık. Daha sonra Struct’ı Class tarafından sınırlanan bloğun dışına almıştık. Class’ların içinde Struct hazırlandığı gibi Struct’ların içinde Class hazırlanabilir. Bu nedenle aşağıda verilen kod hataya neden olmaz.

public partial struct oyuncular
{
  public string ad;
  public double boy;
  public string takim;
  public oyuncular(string Par1, double Par2, string Par3)
   {
    this.ad = Par1;
    this.boy = Par2;
   this.takim = Par3;
  }
 class sinif
  {
  }
}


Şimdi pratik değeri olmasa bile struct’lar hakkında anlatılanların kavranmasına katkı yapacak bir örnek hazırlayacağız. Bu amaçla projenin formunu aşağıdaki gibi düzenledik. Oyuncuya ait bilgiler TextBox’lara girilip ‘Ekle’ düğmesi tıklanacak.



“Ekle” düğmesi tıklandığında struct’ın örneği hazırlanıp TextBox’ların içerikleri struct’ın elemanlarına aktarılacaktır. Devamında ise oyuncular tipindeki dizi değişkene aktarılacak. En son olarak dizi değişkende saklanan bilgiler diğer formdaki ListBox’lara aktarılacaktır. 

“Dizi” değişkenindeki bilgiler diğer formdaki ListBox’lara aktarılmak istediğinde ise “Aktar” düğmesi tıklanacak. “Ekle” düğmesi için hazırladığımız kod aşağıdadır. 

oyuncular[] Dizi, Dizi_temp;
private void ekle_Click(object sender, EventArgs e) 
 
    oyuncular nesne; 
    string str_ad = textBox1.Text; 
    double boyu = Convert.ToDouble(textBox2.Text); 
    string str_takim = textBox3.Text; 
    nesne.ad = str_ad; 
    nesne.boy = boyu; 
    nesne.takim = str_takim;  
    textBox1.Text = ""; 
    textBox2.Text = ""; 
    textBox3.Text = ""; 
    if (Dizi == null) 
    
       Dizi = new oyuncular[1]; 
       Dizi[0] = (oyuncular)nesne; 
    
    else
    
      int sayi = Dizi.Length; 
      Dizi_temp = new oyuncular[sayi]; 
      for (int i = 0; i < sayi; i++) 
        
          Dizi_temp[i] = Dizi[i]; 
        
       Dizi = new oyuncular[sayi + 1]; 
       for (int i = 0; i < sayi; i++) 
         
           Dizi[i] = Dizi_temp[i]; 
         
       Dizi[sayi] = (oyuncular)nesne; 
     
  

Son derece basit olan bu kodda önce “Ekle” düğmesinin Click olayını temsil eden metodun üst kısmında “Dizi” ve “Temp_dizi” adında ve oyuncular tipinde(“oyuncular” hazırlamış olduğumuz yapıdır) 2 dizi değişken tanımladık. Oyuncu ekleme işleminden sonra her seferinde bu dizi değişken yeniden boyutlanacaktır. TextBox’lara girilen bilgileri “oyuncular” adını verdiğimiz struct’ın örneğinin alanlarına aktarıp  TextBox’ların içeriklerini temizledik. 

Devamında dizi değişkenin null olup olmadığını, başka bir deyişle new anahtar kelimesi ile oluşturulup oluşturulmadığını öğrendik. Program henüz çalıştırılmış ve “Ekle” düğmesi ilk kez tıklandıysa dizi değişken null olacaktır. Dizi değişken null ise tanımlayıp 1 elemana sahip olmasını sağlayıp struct’ın örneğini ilk elemanına aktardık. 

Dizi değişken null değilse, başka bir deyişle “Ekle” düğmesi 2. veya 3. kez tıklanıyorsa “Dizi” adını verdiğimiz değişkenin içeriğini “Temp_dizi” adlı diğer değişkene aktarıp “Dizi” değişkeni yeniden hazırlayıp Temp_dizi’nin bütün elemanlarını aktardık. Oyuncu ekleme işlemi tamamlandıktan sonra tıklanacak “Aktar” düğmesi için yazdığımız kod aşağıdadır. 

private void Aktar_Click(object sender, EventArgs e) 
 
    Form2 F = new Form2(); 
    int sayi= Dizi.Length; 
    for (int i = 0; i < sayi; i++) 
     
        F.listBox1.Items.Add(Dizi[i].ad); 
        F.listBox2.Items.Add(Dizi[i].boy.ToString()); 
        F.listBox3.Items.Add(Dizi[i].takim); 
     
    F.Show(); 
  } 

Form2’deki ListBox’lara Form1’den direk ulaşabilmek için her üçünü de public yaptık. Birkaç basketbol oyuncusunun adını, boyunu ve takımını girip “Aktar” düğmesini tıklayınca aşağıdaki gibi bir sonuç aldık.



Enum – Sayılabilir Tipler 

Programcılar programın işletimi sırasında bilgi saklamak üzere daha önce anlatılan hazır tipleri kullandıkları gibi kendi tiplerini hazırlayıp kullanabilirler. Programcılar kendi tiplerini hazırlarken daha çok Class’ları, yapıları(Struct), dizi değişkenler ve Enum’ları tercih ediyorlar. Bu arada .NET Framework ile birlikte çok sayıda Enun tipinin, başka bir adlandırma ile numaralayıcının hazır olarak geldiğini belirtmek gerekir. 

Küçük veriler söz konusu olduğunda sınıf(class) yerine yapı(struct) kullanmak daha pratik ve verimli olabilmektedir. Bu nedenle yapının yeterli olduğu durumlarda tercihinizi yapıdan yana kullanmanız önerilir. Bu kısımda Enum(sayılabilir) tipler hakkında bilgi verilecektir. Örnek vermek gerekirse Windows’un her mesajının bir numarası bulunmaktadır. Hangi numaralı mesajın hangi işlemi temsil ettiğini programcı için akılda tutmak zor olduğu için mesajlara işlevini çağrıştıran adlar verip bunları Enum olarak bir CS dosyasına yazıp her uygulamanızda kullanıp gerek duyduğunuz mesajı kolayca hatırlayabilirsiniz.



Sayılabilir tipler söz konusu değişkenin alabileceği değerler önceden belli ise işlevsel olmaktadır. Bu tip bilgilere haftanın günleri ve mevsimler örnek olarak verilebilir. Başka bir anlatımla, sayılabilir tipler, sayısal değerleri anlamlı adlarla ifade etmemize yardımcı olmaktadır. Aşağıda verilen kodda “Mevsimler” adında bir enum tipi tanımladık. Enum tiplerini tanımlarken public, private ve protected kapsam belirteçlerini kullanabilirsiniz.



Bu şekilde “Mevsimler” adında enum tipini hazırladıktan sonra bu tipten yararlanarak değişken tanımlayıp kullanabilirsiniz. Aşağıda “Mevsimler” tipinden yola çıkarak “Bu_Mevsim” adında bir değişken tanımladık. “Bu_Mevsim” değişkenine bilgi aktarırken Visual Studio aktarabileceğimiz seçenekleri listeledi.



Şimdi “Mevsimler” tipindeki “Bu_Mevsim” değişkenin içeriğini int tipinde bir değişkene aktaracağız. Aktarma işlemi sırasında dönüştürme yapılmazsa hata meydana gelir. “Mevsim” değişkenine “Kış” bilgisini aktardığımız için “Sira” değişkenin içeriği 3 olur.



Bu metot işletildiğinde ilk TextBox’a “Kış” ve 2. TextBox’a ise 3 aktarılır. Çünkü “Kış” seçeneğinin enum tipi içindeki sıra numarası 4’tür. İlk elemanın sıra numarası 0’dan başlamaktadır. “Mevsimler” tipindeki değişkene “Yaz” bilgisini aktarmak istiyorsanız aşağıdaki gibi bir satır yazabilirsiniz. 

Bu_Mevsim = (Mevsimler)1; 

Yukarıda tanımlayıp “Mevsimler” adını verdiğimiz enum tipinde ilk olarak yazılan elemana(ilkbahar) 0, 2. sırada yazılan elemana ise 1 sıra numarası verilir. İsterseniz elemanlara kendiniz sıra numarası verebilirsiniz. Bu nedenle “Mevsimler” adını verdiğimiz Enum tipi aşağıdaki gibi tanımlanırsa değişen bir şey olmaz.
 

public enum Mevsimler 
 
   ilkbahar = 0, 
   yaz = 1, 
   sonbahar = 2, 
   kis = 3 
 

Enum tipinin elemanlarına verilen sıra numaralarının veya aktarılan bilgilerin int tipinde olduğu varsayılmaktadır. Kendi tanımladığınız enum tipinin elemanları fazla değilse int yerine byte veya başka bir tamsayı tipi(short, ushort, long, ulong) kullanılabilir. 

public enum Mevsimler : byte 
 
   ilkbahar=0, 
   yaz=1, 
   sonbahar=2, 
   kis=3 
 

Enum tipinin elemanlarına sayısal değer aktarırken bütün elemanlara 2. elemanın içeriği ilk elemandan 1 fazla olacaksa, başka bir deyişle elemanların içeriği sıralı bir şekilde artıyorsa ilk eleman hariç diğerlerini belirtmek zorunda değilsiniz. 

public enum Yillar 
 
   ilkyil = 2005, 
   ikinciyil, 
   ucuncuyil, 
   dorduncuyil 
 

Bu şekilde tanımlanan enum tipinde “ikinciyil” adını verdiğime elemana 2006, diğerlerine ise 2007 ve 2008 bilgileri aktarılmış varsayılır. Bu nedenle aşağıda verilen kod işletilirse formun başlığına 2006 yazıılır. 

private void button1_Click(object sender, EventArgs e) 
 
   Yillar buyil = Yillar.ikinciyil; 
   int yil = (int)buyil; 
   this.Text = yil.ToString();  
 

Enum değişkeninde saklanan bilginin tipini öğrenmek istiyorsanız GetTypeCode() metodundan yararlanabilirsiniz. Bu metodun nasıl kullanıldığını aşağıda görebilirsiniz. Bu kod işletildiğinde forma yerleştirilen TextBox’a Enum’un tipi aktarılır. Enum’un tipi int ise TextBox’a “Int32”, byte ise “Byte” aktarılır. 

private void button1_Click(object sender, EventArgs e) 
 
   Mevsimler Bu_mevsim; 
   Bu_mevsim = (Mevsimler)2; 
   textBox1.Text = Bu_mevsim.GetTypeCode().ToString(); 


Konunun iyice anlaşılmasını sağlamak için başka bir örnek hazırlayacağız. Bu amaçla ilk olarak “Aylar” adından bir enum tipi hazırladık. 

public enum Aylar 
 
    Ocak=1, Şubat=2, Mart=3, 
    Nisan=4, Mayıs=5, Haziran=6, 
    Temmuz=7, Ağustos=8, Eylül=9, 
    Ekim=10, Kasım=11, Aralık=12 
 

Proje çalıştırıldığında geçerli tarihe uygun olarak ay bilgisinin forma yerleştirdiğimiz Label’a yazılmasını sağlamak üzere formun Load olayını temsil eden metodu aşağıdaki gibi düzenledik. 

int Ay;
private void Form1_Load(object sender, EventArgs e) 
 
   DateTime Tarih; 
   Aylar Bu_ay; 
   Tarih = DateTime.Today; 
   Ay = (int)Tarih.Month; 
   Bu_ay = (Aylar)Ay; 
   this.label1.Text = Bu_ay.ToString();    
 

Diğer metotlarda kullanmak üzere “Ay” adında ve int tipinde bir değişkeni bu metodun dışımda tanımladık. Bu kodda önce geçerli tarihin ay bilgisini öğrenip “Ay” adlı değişkene aktardık. Ardından Enum tipinden ay ilgili ay bilgisini öğrenip Label’a yazdık. Aşağıda verilen ekran görüntüsünü ilk formunun Load olayını temsil eden metodu bu şekilde düzenlenen projeyi çalıştırdıktan sonra aldık.



Bu sırada “Sonraki” veya “Önceki” başlıklı düğmeler tıklandığında label nesnesine yazılan ay bilgisinin değişmesini sağlamak için aşağıdaki gibi kod yazdık. Benzer kodu “Önceki” düğmesi için yazabilirsiniz. 

private void Sonraki_Click(object sender, EventArgs e) 
 
   Aylar Bu_ay; 
   Ay += 1; 
   Bu_ay = (Aylar)Ay; 
   this.label1.Text = Bu_ay.ToString();    
 

Enum Sınıfı 

Sayılabilir tipler üzerinde işlem yaparken System’de bulunan Enum sınıfının metotlarından yararlanabilirsiniz. Bu sınıftaki metotların nasıl kullanıldığını anlatmak için “Aylar” adında bir enum tipi tanımladık. Bu sayılabilir tipi hazırlamadan önce üzerinde çalıştığımız projeye içeriği boş bir Code dosyası dahil edip Enum’un bu kod dosyasında yer almasını sağladık.



Bu şekilde enum tipi tanımladıktan sonra projedeki ilk formun Click olayını temsil eden metodunda string tipte bir dizi değişken tanımlayıp GetNames() metodu ile enum tipinin elemanlarını bu dizi değişkene aşağıdaki gibi aktardık. En son olarak bu dizi değişkenin içeriğini ListBox’a aktardık.
GetNamesmetodu ile dizi değişkene aktarılan elemanları elde ederken for yerine foreach döngüsünden yararlanabilirsiniz. 

private void Form1_Click(object sender, EventArgs e) 
 
   string[] Ay_dizi = Aylar.GetNames(typeof(Aylar)); 
   for (int i = 0; i < 12; i++) 
      listBox1.Items.Add(Ay_dizi[i]);  
 

Enum tipinin bütün elemanları yerine yalnızca bir elemanı ile ilgileniyorsanız GetNames() yerine GetName() metodunu kullanabilirsiniz. İlgilendiğiniz elemanın sıra numarasını GetName() metoduna 2. parametre olarak vermeniz gerekir. Bu metodun nasıl kullanıldığını aşağıda görebilirsiniz. 

private void button1_Click(object sender, EventArgs e) 
 
   string ay = Aylar.GetName(typeof(Aylar), 3); 
   this.Text = ay;   // nisan 
 

Şimdi daha işlevsel bir enum tipi tanımlayacağız. Bazı kamu kuruluşlarında elemanlar sicil numaraları ile anılırlar veya belli sayıda ürünün satışını yapan firmalar ürünün adı yerini kodunu kullanırlar. Bu gibi durumlarda kişinin sicil numarasını veya ürünün kodunu yazmak zorunda kalmamak için enum tipi tanımlayabilirsiniz. 

Yukarıda enum tipi tanımlarken elemanları temsil edecek sayısal bilgileri belirtmedik. Bu değerlerin int tipinde olacağı varsayılmaktadır. Elemanlara sıfırdan başlayan ve ardışık değerlerin aktarılmasını istemiyorsanız elemana istediğiniz değeri aktarabilirsiniz. 

enum iller : byte

  Adana = 1, 
  Ankara = 6, 
  Antalya = 7, 
  Bursa = 16, 
  Eskişehir = 26, 
  Gaziantep = 27, 
  İstanbul = 34, 
  İzmir = 35


İllerin plaka numaralarını girmek yerine adlarını bir liste kutusundan seçmek için enum tipini tanımladıktan sonra projenin ilk formuna bir ComboBox yerleştirip bu formun Load olayını temsil eden metodu aşağıdaki gibi düzenledik. 

private void Form1_Load(object sender, EventArgs e) 
 
   string[] il_dizi = iller.GetNames(typeof(iller)); 
   foreach (string il in il_dizi) 
     comboBox1.Items.Add(il);   
 

Bu satırlar sayesinde sayılabilir tipin elemanları ComboBox’ta listelenir. Elemanları “Bursa=16” gibi tanımlamış olmama rağmen Combobox’ta yalnızca il adları listelenir. ComboBox’ta seçilen ilin plakasını göstermek için forma bir TextBox yerleştirip ComboBox’ta seçim yapıldığında işletilecek metodu aşağıdaki gibi düzenledik.



Fazla pratik değeri olmayan bu kodu konu anlaşılsın diye hazırladık. Bu şartlarda proje çalıştırılıp ComboBox’ta herhangi bir il seçilirse aşağıdaki gibi sonuç alınır.



Programcı kod dahilinde “plaka==27” yazacağına plaka== (
byte)iller.Gaziantepyazacaktır. Bu sayede kod daha okunur olacaktır. Buradaki byte enum’un veri tipini işaret etmektedir. Enum sınıfının Parse() metodu olmasaydı yukarıda verilen koda ekleme yapmaz veya üzerinde konuşmayı burada keserdik. Enum sınıfının Parse() metodunun nasıl kullanıldığını aşağıda görebilirsiniz. 

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) 
 
   string secilen= comboBox1.Text; 
   byte plaka = (byte)Enum.Parse(typeof(iller), secilen, true); 
   textBox1.Text = plaka.ToString();  
 

Parse() metodu kendisine 2. parametre olarak verilen bilgiyi 1. parametrede verilen Enum tipinde aramaktadır. Parse() metodunun bool tipte olan 3. parametresi Enum’da arama yapılırken küçük büyük harf ayrımının yapılıp yapmayacağı ile ilgilidir. 3. parametre olarak false kullanılırsa aramada küçük büyük harf ayrımı yapılır. Bu kod sayesinde ComboBox’ta seçilen ilin plakası TextBox’a aktarılır. Parse() metodu ile Enum tipte aranan bilgi bulunamazsa hata meydana gelir. 

Format Metodu 

Enum sınıfının yukarıda sözü edilen Parse() metodundan başka ayrıca Format() metodu bulunmaktadır. Bu metot sayesinde enum tipinin elemanlarını biçimleyebilirsiniz. Bu metodun nasıl kullanıldığını anlatmak için aşağıda verilen kodu yazdık.   

private void Form1_Click(object sender, EventArgs e) 
 
   iller il = iller.Adana; 
   textBox1.Text = il.ToString(); 
 } 

Tahmin edeceğiniz gibi bu kod işletildiğinde TextBox’a “Adana” yazılır. Tabii TextBox’a Adana yerine bu ilin Enum’daki sıra numarasının yazılmasını istemiş olsaydık Parse() metodunu aşağıdaki gibi kullanırdık. 

byte plaka = (byte)Enum.Parse(typeof(iller), "Adana", true);
textBox1.Text = plaka.ToString();    

Ne var ki bu kullanım bazen pratik olmaz. Örneğin TextBox’a 1 yerine “01” yazmak istenebilir. Bu gibi durumlarda Enum sınıfının Format() metodunu kullanmak gerekir. Bu metodun nasıl kullanıldığını aşağıda görebilirsiniz. 

private void Form1_Click(object sender, EventArgs e) 
 
   iller il = iller.Adana ; 
   string str = Enum.Format(typeof(iller), il, "G"); 
   textBox1.Text =str; 
 

Bu kodda önce kendi hazırlamış olduğumuz enum tipinde bir değişken tanımlayıp “Adana” adlı elemanı bu değişkene aktardık. Ardından bu hazırladığımız enum tipindeki(il) değişkeni Format metoduna 2. parametre olarak verdik. Format() metodunun 1. parametresi Parse() metodunda olduğu typeof() operatörü ile elde edilen tiptir. Format() metoduna 3. parametre olarak “G” karakterini verdik. Bu şekilde düzenlenen Format() metodu geriye “Adana” bilgisini gönderir. Format() metodunun geriye söz konusu elemanın enum’daki sırasını geri göndermesini istemiş olsaydık aşağıdaki gibi kullanırdık. 

iller il = iller.Adana ;
string  str = Enum.Format(typeof(iller), il,  "D");
textBox1.Text = str; 

Bu kod işletildiğinde TextBox’a “1” yazılır. TextBox’a 1 yerine “01” yazmak isteseydik Format() metoduna 3. parametre olarak “X” karakterini verirdik. 

iller il = iller.Adana ;
string str = Enum.Format(typeof(iller), il, "X");
textBox1.Text = str; 

GetValues Metodu 

Yukarıdaki sayfalarda Enum sınıfının GetNames() metodundan yararlanıp ilgili Enum’daki bilgileri veya adları elde edip ListBox’a aktarmıştık. Daha sonra programcı seçtiği enum sabitinden yola çıkıp o sabitin temsil ettiği değeri bulup ona göre işlem yapmıştık. Enum sınıfının GetValues() metodundan yararlanıp enum sabitinin değerlerini elde edebilirsiniz. 

Bu metodun nasıl kullanıldığını anlatırken yukarıda verilen “iller” adını verdiğimiz sayılabilir tipten yararlanacağız. Forma 2 ListBox yerleştirdikten sonra aşağıda verilen kodu yazdık. 

private void Form1_Load(object sender, EventArgs e) 
 
   string[] il_dizi = iller.GetNames(typeof(iller)); 
   foreach (string il in il_dizi) 
      listBox1.Items.Add(il); 
   int sayi = il_dizi.Length;  
   Array plaka_dizi=Array.CreateInstance(typeof(byte), sayi); 
   plaka_dizi = iller.GetValues(typeof(iller)); 
   foreach (byte plaka in plaka_dizi) 
     listBox2.Items.Add(plaka.ToString() ); 
 

Bu kod sayesinde ilk ListBox’ta enum dahilindeki iller, 2. ListBox’ta ise illerin plakaları listelenir. Enum sınıfının GetValues() metodu geriye Array nesnesi gönderdiği için önceden bir dizi değişken tanımladık. 

Enum’da Veya Operatörünü Kullanmak 

.NET Framework ile gelen bir çok Enum tipinde içinde bulunulan şartlara göre “veya” durumları söz konusu olabilmektedir. Kendi hazırladığınız Enum tipte farklı seçimler yapılsa bile aynı işlemi yaptırtmak isteyebilirsiniz. Örneğin söz konusu kişinin öğrenim durumunu seçerken hazırladığınız sayılabilir tipte, hem lisans hem de yüksek lisans seçeneklerine aynı işlevi yükleyebilirsiniz. Bunu örneklemek için aşağıdaki gibi bir Enum hazırladık. 

public enum ogrenim_durumu :byte 
 
   ilk = 1, 
   orta = 2, 
   lise = 3, 
   lisans = 4, 
   yuksek_lisans = 5, 
 

Bu şekilde enum tipi hazırladıktan sonra aşağıdaki kod yazarak ilgili öğrenim durumu seçeneğinin sıra numarasını TextBox’a aktardık. Aşağıda verilen kodda sizin için herhangi bir yenilik yoktur. 

private void Form1_Click(object sender, EventArgs e) 
 
   ogrenim_durumu ogrenim = ogrenim_durumu.ilk; 
   byte sira = (byte)ogrenim; 
   textBox1.Text = sira.ToString(); 
 

Bu kod işletildiğinde TextBox’a 1 yazılır. Eğer öğrenim durumu ilk ve orta okul olanları aynı grubu dahil etmek istiyorsanız bu kodu aşağıdaki gibi yazabilirsiniz. 

private void Form1_Click(object sender, EventArgs e) 
 
   ogrenim_durumu ogrenim = ogrenim_durumu.ilk | ogrenim_durumu.orta;   
   byte sira = (byte)ogrenim; 
   textBox1.Text = sira.ToString(); 
 

Tahmin edeceğiniz gibi bu kod işletildiğinde TextBox’a 3 yazılır. Ne ki hazırladığımız Enum’da 3 ile öğrenim durumu lise olanlar işaret edilmektedir. Bu nedenle “veya” kullanılacak enum sabitlerinin seçeneklerine sabit değer verilirken dikkatli olmak gerekir. Bizim örnekte en basit şekli ile öğrenim durumu ilk ile orta olan toplanır ki 3 değeri elde edilir. 

Buna göre 3. sıradaki “Lise” öğrenim seçeneği için en az 4 değeri seçilmelidir. 4. sıradaki seçeneği temsil edecek sayısal değer ilk üçünün toplamından en azından 1 fazla olmalıdır. Enum aşağıdaki gibi düzenlenirse yukarıda sözünü ettiğimiz sorun yaşanmaz. 

public enum ogrenim_durumu : byte 
 
   ilk = 1, 
   orta = 2, 
   lise = 4, 
   lisans = 8, 
   yuksek_lisans = 16, 
 

Bu durumda 2 ortayı, 3 ise “ilk veya ortayı”, 5 “ilk veya liseyi”, 6 “orta veya liseyi” temsil eder. Bu nedenle aşağıda verilen kod işletilirse TextBox’a 7 yazılır. 

private void Form1_Click(object sender, EventArgs e) 
 
   ogrenim_durumu ogrenim= ogrenim_durumu.ilk | 
              ogrenim_durumu.orta | ogrenim_durumu.lise ;   
   byte sira = (byte)ogrenim; 
   textBox1.Text = sira.ToString(); 
 

Enum sınıfının yukarıda sözü edilen özellik ve metotlarından başka ayrıca Enum’da arama yapılırken kullanılan IsDefined() adında bir metodu var. Bu metot sayesinde sözü edilecek seçeneğin Enum tipinde yer alıp almadığı öğrenilmektedir. 

private void Form1_Click(object sender, EventArgs e) 
 
   bool sonuc = Enum.IsDefined(typeof(ogrenim_durumu), "lise");   
   textBox1.Text = sonuc.ToString(); 
 

IsDefined() metodunun ilk parametresi ile aramaya konu edilecek enum tipi işaret edilirken 2. parametrede aranmak istenen seçenek verilmektedir. Yukarıda “ogrenim_durumu” adını verdiğimiz enum’da “lise” adında bir seçenek olduğu için bu kod işletildiğinde IsDefined() metodu geriye true gönderir. 

Şimdi enum’ların başka bir özelliği hakkında bilgi vermek için 4 elemana sahip yeni bir tipi hazırladık. Bu enum örneğinde “hepsi” seçeneğinin sıra içeriğini doğrudan yazmak yerine veya operatöründen yararlandık. 

public enum diller : byte 
 
   ingilizce = 1, 
   almanca = 2, 
   fransizca = 4, 
   italyanca = 8, 
   hepsi = ingilizce | almanca | fransizca | italyanca 
 

Aşağıda verdiğim kodu dikkatlice incelerseniz “hepsi” elemanın 15 değerini içeriğini tahmin edebilirsiniz. Bu nedenle bu kod işletilirse TextBox’a 15 yazılır. 

       
private void Form1_Click(object sender, EventArgs e) 
         
           diller dil = diller.hepsi; 
           byte sira = (byte)dil; 
           textBox1.Text = sira.ToString(); 
         }

* Daha önce satın aldığınız C# kitaplarında Struct ve Enum’lar hakkında bu kadar bilgi yoksa hemen kitapların yazarlarını suçlamayınız. Hele hele bu yazarlar değişken adı sahibi olacak kadar zirvelere çıkmışlarsa kendilerini taktir etme borcunuzun olduğunu lütfen unutmayınız.

C# 3.0 Kitabı 09.12.2009 23:21:54

4 YORUM


YorumlarYorum Yaz
Ana Sayfa | Hakkımda | Kitap Önerileri | Fotoğraflarım | RSS | İletişim
Memik Yanık 2004-2009 © Tüm Hakları Saklıdır.
Hazırlayan www.semgoksu.com