C#’ta Hashtable Koleksiyon Sınıfının Kullanımı

Hashtable Koleksiyon Sınıfının Kullanımı

Bu makalemizde HashTable koleksiyon sınıfını incelemeye çalışacağız. Bildiğiniz gibi Koleksiyonlar System.Collections namespace’inde yer almakta olup, birbirlerinin aynı veya birbirlerinden farklı veri tiplerinin bir arada tutulmasını sağlayan diziler oluşturmamıza imkan sağlamaktadırlar. Pek çok koleksiyon sınıfı vardır. Bugün bu koleksiyon sınıflarından birisi olan HashTable koleksiyon sınıfını inceleyeceğiz.

HashTable koleksiyon sınıfında veriler key-value dediğimiz anahtar-değer çiftleri şeklinde tutulmaktadırlar. Tüm koleksiyon sınıflarının ortak özelliği barındırdıkları verileri object tipinde olmalarıdır. Bu nedenle, HashTable’lardada key ve value değerleri herhangibir veri tipinde olabilirler. Temel olarak bunların her biri birer DictionaryEntry nesnesidir. Bahsetmiş olduğumuz key-value çiftleri hash tablosu adı verilen bir tabloda saklanırlar. Bu değer çiftlerine erişmek için kullanılan bir takım karmaşık kodlar vardır.

Key değerleri tektir ve değiştirilemezler. Yani bir key-value çiftini koleksiyonumuza eklediğimizde, bu değer çiftinin value değerini değiştirebilirken, key değerini değiştiremeyiz. Ayrıca key değerleri benzersiz olduklarında tam anlamıyla birer anahtar alan vazifesi görürler. Diğer yandan value değerline null değerler atayabilirken, anahtar alan niteliğindeki Key değerlerine null değerler atayamayız. Şayet uygulamamızda varolan bir Key değerini eklemek istersek ArgumentException istisnası ile karşılaşırız.

HashTable koleksiyonu verilere hızı bir biçimde ulaşmamızı sağlayan bir kodlama yapısına sahiptir. Bu nedenle özellikle arama maliyetlerini düşürdüğü için tercih edilmektedir. Şimdi konuyu daha iyi pekiştirebilmek amacıyla, hemen basit bir uygulama geliştirelim. Uygulamamızda, bir HastTable koleksiyonuna key-value çiftleri ekliyecek, belirtilen key’in sahip olduğu değere bakılacak, tüm HashTable’ın içerdiği key-value çiftleri listelenecek, eleman çiftlerini HashTable’dan çıkartacak vb… işlemler gerçekleştireceğiz. Form tasarımını ben aşağıdaki şekildeki gibi yaptım. Temel olarak teknik terimlerin türkçe karşılığına dair minik bir sözüğü bir HashTable olarak tasarlayacağız.

Şekil 1. Form Tasarımımız.

Şimdi kodlarımıza bir göz atalım.

System.Collections.Hashtable htTeknikSozluk; /* HashTable koleksiyon nesnemizi tanimliyoruz.*/

private void Form1_Load(object sender, System.EventArgs e)
{
     htTeknikSozluk=new System.Collections.Hashtable(); /* HashTable nesnemizi olusturuyoruz.*/
    stbDurum.Text=htTeknikSozluk.Count.ToString(); /* HashTable’imizdaki eleman sayisini Count özelligi ile ögreniyoruz.*/
}

private void btnEkle_Click(object sender, System.EventArgs e)
{
     try
     {
         htTeknikSozluk.Add(txtKey.Text,txtValue.Text);/* HashTable’imiza key-value çifti ekleyebilmek için Add metodu kullaniliyor.*/
        lstAnahtar.Items.Add(txtKey.Text);
        stbDurum.Text=htTeknikSozluk.Count.ToString();
     }
    catch(System.ArgumentException) /* Eger var olan bir key’i tekrar eklemeye çalisirsak bu durumda ArgumentException istisnasi     firlatilacaktir. Bu durumda, belirtilen key-value çifti HashTable koleksiyonuna eklenmez. Bu durumu kullaniciya bildiriyoruz.*/
    {
         stbDurum.Text=txtKey.Text+” Zaten HashTable Koleksiyonunda Mevcut!”;
    }
}

private void lstAnahtar_DoubleClick(object sender, System.EventArgs e)
{
    string deger;

    deger=htTeknikSozluk[lstAnahtar.SelectedItem.ToString()].ToString(); /* HashTable’daki bir degere ulasmak için, köseli parantezler arasinda aranacak key degerini giriyoruz. Sonucu bir string degiskenine aktariyoruz.*/

    MessageBox.Show(deger,lstAnahtar.SelectedItem.ToString());
}

private void btnSil_Click(object sender, System.EventArgs e)
{
    if(htTeknikSozluk.Count==0) 
    {
        stbDurum.Text=”Çikartilabilecek hiç bir eleman yok”;
     }
    else if(lstAnahtar.SelectedIndex==-1)
    {
        stbDurum.Text=”Listeden bir eleman seçmelisiniz”;
    }
    else
    {
         htTeknikSozluk.Remove(lstAnahtar.SelectedItem.ToString()); /* Bir HashTable’dan bir nesneyi çikartmak için, Remove metodu kullanilir. Bu metod parametre olarak çikartilmak istenen deger çiftinin key degerini alir.*/

        lstAnahtar.Items.Remove(lstAnahtar.SelectedItem);

        stbDurum.Text=”Çikartildi”;

        stbDurum.Text=htTeknikSozluk.Count.ToString();
     }
}

private void btnTumu_Click(object sender, System.EventArgs e)
{
    lstTumListe.Items.Clear(); /* Asagidaki satirlarda, bir HashTable koleksiyonu içinde yer alan tüm elemanlara nasil erisildigini görmekteyiz. Keys metodu ile HashTable koleksiyonumuzda yer alan tüm anahtar degerlerini (key’leri), ICollection arayüzü(interface) türünden bir nesneye atiyoruz. Foreach döngümüz ile bu nesne içindeki her bir anahtari, HashTable koleksiyonunda bulabiliyoruz.*/

    ICollection anahtar=htTeknikSozluk.Keys; foreach(string a in anahtar)
    {
        lstTumListe.Items.Add(a+”=”+htTeknikSozluk[a].ToString());
     }
}

Şimdi uygulamamızı çalıştıralım.


Şekil 2. Programın Çalışmasnının sonucu.

Geldik bir makalemizin daha sonuna. Bir sonraki makalemizde görüşmek dieğiyle hepinize mutlu günler dilerim.

 

 

 

 

Stack ve Queue Koleksiyon Sınıfları

Bu makalemizde Stack ve Queue koleksiyon sınıflarını incelemeye çalışacağız. Bir önceki makalemizde bildiğiniz gibi, HashTable koleksiyon sınıfını incelemeştik. Stack ve Queue koleksiyonlarıda, System.Collections isim alanında yer alan ve ortak koleksiyon özelliklerine sahip sınıflardır.

Stack ve Queue koleksiyonları, her koleksiyon sınıfında olduğu gibi, elemanlarını object tipinde tutmaktadırlar. Bu koleksiyonların özelliği giren-çıkan eleman prensibleri üzerine çaılşmalarıdır. Stack koleksiyon sınıfi, LIFO adı verilen, Last In First Out( Son giren ilk çikar) prensibine gore çalışırken, Queue koleksiyon sınıfı FIFO yani First In First Out(ilk giren ilk çıkar) prensibine gore çalışır. Konuyu daha iyi anlayabilmek için asağıdaki şekilleri göz önüne alalım.

 

Sekil 1. Stack Koleksiyon Sınıfının Çalışma Yapısı
Görüldüğü gibi, Stack koleksiyonunda yer alan elemanlardan son girene ulaşmak oldukça kolaydır. Oysaki ilk girdiğimiz elemana ulaşmak için, bu elemanın üstünde yer alan diğer tüm elemanları silmemiz gerekmektedir. Queue koleksyion sınıfına gelince;

 

Sekil 2. Queue Koleksiyon Sınıfının Çalışma Yapısı

Görüldügü gibi Queue koleksiyon sinifinda elemanlar koleksiyona arkadan katilirlar ve ilk giren eleman kuyruktan ilk çikan eleman olur.

Stack ve Queue farklı yapılarda tasarlandıkları için elemanlarına farklı metodlar ile ulaşılmaktadır. Stack koleksiyon sınıfında, en son giren elemanı elde etmek için Pop metodu kullanılır. Koleksiyona bir eleman eklerken Push metodu kullanılır. Elbette eklenen eleman en son elemandır ve Pop metodu çağrıldığında elde edilecek olan ilk eleman halini alir. Ancak Pop metodu son giren elemanı verirken bu elemanı koleksiyondan siler. İşte bunun önüne geçen metod Peek metodudur. Şimdi diyebilirsiniz ki madem son giren elemanı siliniyor, Pop metodunu o zaman niye kullanıyoruz. Hatırlarsanız, Stack koleksiyonunda, ilk giren elemanı elde etmek için bu elemanın üstünde yer alan tüm elemanları silmemiz gerektiğini söylemiştik. İşte bir döngü yapısında Pop metodu kullanıldığında, ilk giren elemana kadar inebiliriz. Tabi diğer elemanlari kaybettikten sonra bunun çok büyük önem taşıyan bir eleman olmasını da istemiş olabiliriz.

Gelelim Queue koleksiyon sınıfının metodlarına. Dequeue metodu ile koleksiyona ilk giren elemani elde ederiz. Ve bunu yaptığımız anda eleman silinir. Nitekim dequeue metodu pop metodu gibi çalışır. Koleksiyona eleman eklemek için ise, Enqueue metodu kullanılır. İlk giren elemanı elde etmek ve silinmemesini sağlamak istiyorsak yine stack koleksiyon sınıfinda olduğu gibi, Peek metodunu kullanırız.

Bu koleksiyonlarin en güzel yanlarından birisi siz eleman sayısını belirtmediğiniz takdirde koleksiyonun boyutunu otomatik olarak kendilerinin ayarlamalarıdır. Stack koleksiyon sınıfı, varsayilan olarak 10 elemanlı bir koleksiyon dizisi oluşturur.(Eğer biz eleman sayısını yapıcı metodumuzda belirtmez isek).Eğer eleman sayısı 10’u geçerse, koleksiyon dizisinin boyutu otomatik olarak iki katina çıkar. Ayni prensip queue koleksiyon sinifi içinde geçerli olmakla birlikte, queue koleksiyonu için varsayilan dizi boyutu 32 elemanli bir dizidir.

Simdi dilerseniz, basit bir console uygulamasi ile bu konuyu anlamaya çalisalim.

using System;
using System.Collections; /* Uygulamalarimizda koleksiyon siniflarini kullanabilmek için Collections isim uzayini kullanmamiz gerekir.*/

namespace StackSample1
{
     class Class1
     {

          static void Main(string[] args)
          {
               Stack stc=new Stack(4); /* 4 elemanli bir Stack koleksiyonu olusturduk.*/

               stc.Push(“Burak”); /*Eleman eklemek için Push metodu kullaniliyor.*/
               stc.Push(“Selim”);
               stc.Push(“SENYURT”);
               stc.Push(27);
               stc.Push(true);

               Console.WriteLine(“Çikan eleman {0}”,stc.Pop().ToString());/* Pop metodu son giren(kalan) elemani verirken, ayni zamanda bu elemani koleksiyon dizisinden siler.*/
               Console.WriteLine(“Çikan eleman {0}”,stc.Pop().ToString());
               Console.WriteLine(“Çikan eleman {0}”,stc.Pop().ToString());
               Console.WriteLine(“——————“);
               
               IEnumerator dizi=stc.GetEnumerator(); /* Koleksiyonin elemanlarini IEnumerator arayüzünden bir nesneye aktariyoruz.*/

               while(dizi.MoveNext()) /* dizi nesnesinde okunacak bir sonraki eleman var oldugu sürece isleyecek bir döngü.*/
               {
                    Console.WriteLine(“Güncel eleman {0}”,dizi.Current.ToString()); /* Current metodu ile dizi nesnesinde yer alan güncel elemani elde ediyoruzç. Bu döngüyü çalistirdigimizda sadece iki elemanin dizide oldugunu görürüz. Pop metodu sagolsun.*/
               }

               Console.WriteLine(“——————“);
               Console.WriteLine(“En üstteki eleman {0}”,stc.Peek()); /* Peek metodu son giren elemani veya en üste kalan elemani verirken bu elemani koleksiyondan silmez.*/

               dizi=stc.GetEnumerator();

               while(dizi.MoveNext())
               {
                    Console.WriteLine(“Güncel eleman {0}”,dizi.Current.ToString()); /* Bu durumda yine iki eleman verildigini Peek metodu ile elde edilen elemanin koleksiyondan silinmedigini görürüz.*/
               }

          }
     }
}

 

3. Stack ile ilgili programın ekran çıktısı

Queue örnegimiz ise aynı kodlardan oluşuyor sadece metod isimleri farklı.

using System;
using System.Collections;

namespace QueueSample1
{
     class Class1
     {
          static void Main(string[] args)
          {
               Queue qu=new Queue(4);

               qu.Enqueue(“Burak”); /*Eleman eklemek için Enqueue metodu kullaniliyor.*/
               qu.Enqueue(“Selim”);
               qu.Enqueue(“SENYURT”);
               qu.Enqueue(27);
               qu.Enqueue(true);

               Console.WriteLine(“Çikan eleman {0}”,qu.Dequeue().ToString());/* Dequeue metodu ilk giren(en alttaki) elemani verirken, ayni zamanda bu elemani koleksiyon dizisinden siler.*/
               Console.WriteLine(“Çikan eleman {0}”,qu.Dequeue().ToString());
               Console.WriteLine(“Çikan eleman {0}”,qu.Dequeue().ToString());
               Console.WriteLine(“——————“);

               IEnumerator dizi=qu.GetEnumerator(); /* Koleksiyonin elemanlarini IEnumerator arayüzünden bir nesneye aktariyoruz.*/
               while(dizi.MoveNext()) /* dizi nesnesinde okunacak bir sonraki eleman var oldugu sürece isleyecek bir döngü.*/
               {
               Console.WriteLine(“Güncel eleman {0}”,dizi.Current.ToString()); /* Current metodu ile dizi nesnesinde yer alan güncel elemani elde ediyoruzç. Bu döngüyü çalistirdigimizda sadece iki elemanin dizide oldugunu görürüz. Dequeue metodu sagolsun.*/
               }

               Console.WriteLine(“——————“);
               Console.WriteLine(“En altta kalan eleman {0}”,qu.Peek()); /* Peek metodu son giren elemani veya en üste kalan elemani verirken bu elemani koleksiyondan silmez.*/

               dizi=qu.GetEnumerator();

               while(dizi.MoveNext())
               {
                    Console.WriteLine(“Güncel eleman {0}”,dizi.Current.ToString()); /* Bu durumda yine iki eleman verildigini Peek metodu ile elde edilen elemanin koleksiyondan silinmedigini görürüz.*/
               }

          }
     }
}

 

Sekil 4. Queue ile ilgili programin ekran çıktısı

Geldik bir makalemizin daha sonuna. Umuyorumki sizlere faydalı olabilecek bilgiler sunabilmişimdir. Bir sonraki makalemizde görüsmek dileğiyle hepinize mutlu günler dilerim.

 

 

 

 

 

 

 

 

 

 

 

Reflection(Yansıma) ile Tiplerin Sırrı Ortaya Çıkıyor

Hiç dotNET ‘te yer alan bir tipin üyelerini öğrenebilmek istediniz mi? Örneğin var olan bir dotNET sınıfının veya sizin kendi yazmış olduğunuz yada bir başkasının yazdığı sınıfa ait tüm üyelerin neler olduğuna programatik olarak bakmak istediniz mi?  

İşte bugünkü makalemizin konusu bu. Herhangi bir tipe (type) ait üyelerin neler olduğunu anlayabilmek. Bu amaçla, Reflection isim uzayını ve bu uzaya ait sınıfları kullanacağız. Bildiğiniz gibi .NET ‘te kullanılan her şey bir tipe aittir. Yani herşeyin bir tipi vardır. Üyelerini öğrenmek isteğimiz bir tipi öncelikle bir Type değişkeni olarak alırız. (Yani tipin tipini alırız. Bu nedenle ben bu tekniğe Tip-i-Tip adını verdim ). Bu noktadan sonra Reflection uzayına ait sınıfları ve metodlarını kullanarak ilgili tipe ait tüm bilgileri edinebiliriz. Küçük bir Console uygulaması ile konuyu daha iyi anlamaya çalışalım. Bu örneğimizde, System.Int32 sınıfına ait üyelerin bir listesini alacağız. İşte kodlarımız; 

using System;
namespace ReflectionSample1
{
     class Class1     
     {
          static void Main(string[] args)
          {
               Type tipimiz=Type.GetType(“System.Int32″);/* Öncelikle String sinifinin tipini ögreniyoruz. */

               System.Reflection.MemberInfo[] tipUyeleri=tipimiz.GetMembers(); /* Bu satir ile, System.String tipi içinde yer alana üyelerin listesini Reflection uzayinda yer alan, MemberInfo sinifi tipinden bir diziye aktariyoruz. */

               Console.WriteLine(tipimiz.Name.ToString()+” sinifindaki üye sayisi:”+tipUyeleri.Length.ToString());/* Length özelligi, MemeberInfo tipindeki dizimizde yer alan üyelerin sayisini, (dolayisiyla                System.String sinifi içinde yer alan üyelerin sayisini) veriyor.*/

               /* Izleyen döngü ile, MemberInfo dizininde yer alan üyelerin birtakim bilgilerini ekrana yaziyoruz.*/
               for(int i=0;i<TIPUYELERI.LENGTH;++I)     
               {
                    Console.WriteLine(i.ToString()+”. üye adi:”+tipUyeleri[i].Name.ToString()+”||”+tipUyeleri[i].MemberType.ToString()); /* Name özelligi üyenin adini verirken, MemberType özelligi ile, üyenin tipini aliyoruz. Bu üye tipi metod, özellik, yapici metod vb… dir.*/
               }
          }
     }
}

 

Uygulamayı çalıştırdığımızda aşağıdaki ekran görüntüsünü elde ederiz.


Şekil 1. System.Int32 sınıfının üyeleri.
 

Üye listesini incelediğimizde 15 üyenin olduğunu görürüz. Metodlar, alanlar vardır. Ayrıca dikkat ederseniz, Parse , ToString metodları birden fazla defa geçmektedir. Bunun nedeni bu metodların overload ( aşırı yüklenmiş ) versiyonlara sahip olmasıdır. 

Kodları incelediğimizde, System.Int32 sınıfına ait tipleri GetMembers metodu ile, System.Reflection uzayında yer alan MemberInfo sınıfı tipinden bir diziye aldığımızı görürüz. İşte olayın önemli kodları bunlardan oluşmaktadır. MemberInfo dışında kullanabaileceğimiz başka Reflection sınıflarıda vardır. Bunlar; 

ConstructorInfo Tipe ait yapıcı metod üyelerini ve bu üyelere ait bilgilerini içerir.
EventInfo Tipe ait olayları ve bu olaylara ait bilgileri içerir.
MethodInfo Tipe ait metodları ve bu metodlara ait bilgileri içerir.
FieldInfo Tip içinde kullanılan alanları ve bu alanlara ilişkin bilgileri içerir.
ParameterInfo Tip içinde kullanılan parametreleri ve bu parametrelere ait bilgileri içerir.
PropertyInfo Tip içinde kullanılan özellikleri ve bu özelliklere ait bilgileri içerir.

Tablo 1. Reflection Uzayının Diğer Kullanışlı Sınıfları 

Şimdi bu sınıflara ait örneklerimizi inceleyelim. 

Bu kez bir DataTable sınıfının üyelerini inceleyeceğiz. Örnek olarak, sadece olaylarını ve bu olaylara ilişkin özelliklerini elde etmeye çalışalım. Bu örneğimizde, yukarıda bahsettiğimiz tip-i-tip tekniğini biraz değiştireceğiz. Nitekim bu tekniği uygulamamız halinde bir hata mesajı alırız. Bunun önüne geçmek için, bir DataTable örneği (instance) oluşturup bu örneğin tipinden hareket edeceğiz. Dilerseniz hemen kodlarımıza geçelim. 

using System;

namespace ReflectionSample2
{

     class Class1
     {
          static void Main(string[] args)
          {
               System.Data.DataTable dt=new System.Data.DataTable(); /* Bir DataTable örnegi(instance) yaratiyoruz.*/

               Type tipimiz=dt.GetType(); /* DataTable örnegimizin GetType metodunu kullanarak, bu örnegin dolayisiyla DataTable sinifinin tipini elde ediyoruz. */

               System.Reflection.MethodInfo[] tipMetodlari=tipimiz.GetMethods(); /* Bu kez sadece metodlari incelemek istedigimizden, GetMethods metodunu kullaniyor ve sonuçlari, MethodInfo sinifi tipinden bir diziye aktariyoruz.*/

               Console.WriteLine(tipimiz.Name.ToString()+” sinifindaki metod sayisi:”+tipMetodlari.Length.ToString()); /* Metod sayisini Length özelligi ile aliyoruz.*/

               /* Döngümüzü olusturuyor ve Metodlarimizi bir takim özellikleri ile birlikte yazdiriyoruz.*/
               for(int i=0;i<TIPMETODLARI.LENGTH;++I)
               {
                    Console.WriteLine(“Metod adi:”+tipMetodlari[i].Name.ToString()+” |Dönüs degeri:”+tipMetodlari[i].ReturnType.ToString()); /* Metodun ismini name özelligi ile aliyoruz. Metodun dönüs tipini ReturnType özelligi ile aliyoruz. */

                    System.Reflection.ParameterInfo[] prmInfo=tipMetodlari[i].GetParameters();
                    /* Bu satirda ise, i indeksli metoda ait parametre bilgilerini GetParameters metodu ile aliyor ve Reflection uzayinda bulunan ParameterInfo sinifi tipinden bir diziye aktariyoruz. Böylece ilgili metodun parametrelerine ve parametre bilgilerine erisebilicez.*/

                     Console.WriteLine(“—–Parametre Bilgileri—–“+prmInfo.Length.ToString()+” parametre”);
                    /* Döngümüz ile i indeksli metoda ait parametrelerin isimlerini ve tiplerini yazdiriyoruz. Bunun için Name ve ParameterType metodlarini kullaniyoruz.*/

                    for(int j=0;j<PRMINFO.LENGTH;++J)
                    {
                         Console.WriteLine(“P.Adi:”+prmInfo[j].Name.ToString()+” |P.Tipi:”+prmInfo[j].ParameterType.ToString());
                    }

                    Console.WriteLine(“—-“);
               }
          }
     }
}

 

Şimdi uygulamamızı çalıştıralım ve sonuçlarına bakalım. 

Şekil 2. System.Data.DataTable tipinin metodları ve metod parametrelerine ait bilgiler. 

Reflection teknikleri yardımıyla çalıştırdığımız programa ait sınıflarında bilgilerini elde edebiliriz. İzleyen örneğimizde, yazdığımız bir sınıfa ait üye bilgilerine bakacağız.  

Üyelerine bakacağımız sınıfın kodları; 

using System;

namespace ReflectionSample3
{
     public class OrnekSinif
     {
          private int deger;

          public int Deger
          {
               get
               {
                    return deger;
               }
               set
               {
                    deger=value;
               }
          }

     public string metod(string a)
     {
          return “Burak Selim SENYURT”;
     }

     int yas=27;
     string dogum=”istanbul”;

     }
}

ikinci sınıfımızın kodları;

using System;
using System.Reflection;

namespace ReflectionSample3
{
     class Class1
     {
          static void Main(string[] args)
          {
               Type tipimiz=Type.GetType(“ReflectionSample3.OrnekSinif”);

               MemberInfo[] tipUyeleri=tipimiz.GetMembers();

               for(int i=0;i<TIPUYELERI.LENGTH;++I)
               {
                    Console.WriteLine(“Uye adi:”+tipUyeleri[i].Name.ToString()+” |Uye Tipi:”+tipUyeleri[i].MemberType.ToString());
               }
          }
     }
}

Şimdi uygulamamızı çalıştıralım.


Şekil 3. Kendi yazdığımı sınıf üyelerinede bakabiliriz.
 

Peki kendi sınıfımıza ait bilgileri edinmenin bize ne gibi bir faydası olabilir. İşte şimdi tam dişimize gore bir örnek yazacağız. Örneğimizde, bir tablodaki verileri bir sınıf içersinden tanımladığımız özelliklere alacağız. Bu uygulamamız sayesinde sadece tek satırlık bir kod ile, herhangibir kontrolü veriler ile doldurabileceğiz. Bu uygulamada esas olarak, veriler veritabanındaki tablodan alınıcak ve oluşturduğumuz bir koleksiyon sınıfından bir diziye aktarılacak. Oluşturulan bu koleksiyon dizisi, bir DataGrid kontrolü ile ilişkilendirilecek. Teknik olarak kodumuzda, Reflection uzayının PropertyInfo sınıfını kullanarak, oluşturduğumuz sınıfa ait özellikler ile tablodaki alanları karşılaştıracak ve uygun iseler bu özelliklere tabloda karşılık gelen alanlar içindeki değerleri aktaracağız. Dilerseniz kodumuz yazmaya başlayalım. 

using System;
using System.Reflection;
using System.Data;
using System.Data.SqlClient;

namespace ReflectDoldur
{
     public class Kitap
     {

          private string kitapAdi;
          private string yayimci;

          /* Özelliklerimizin adlarinin tablmuzdan alacagimiz alan adlari ile ayni olmasina dikkat edelim.*/
          public string Adi
          {
               get
               {
                    return kitapAdi;
               }
              set
              {
                   kitapAdi=value;
              }
         }

         public string BasimEvi
         {
              get
              {
                   return yayimci;
              }
              set
              {
                   yayimci=value;
              }
         }

         /* Yapici metodumuz parametre olarak geçirilen bir DataRow degiskenine sahip. Bu degisken ile o anki satiri aliyoruz.*/
         public Kitap(System.Data.DataRow dr)
         {
              PropertyInfo[] propInfos=this.GetType().GetProperties(); /* this ile bu sinifi temsil ediyoruz. Bu sinifin tipini alip bu tipe ait özellikleri elde ediyor ve bunlar bir PropertyInfo sinifi tipinden diziye aktariyoruz.*/

              /* Döngümüz ile tüm özellikleri geziyoruz. Eger metodumuza parametre olarak geçirilen dataRow degiskenimiz, bu özelligin adinda bir alan içeriyorsa, bu özellige ait SetValue metodunu kullanarak özelligimize, iligili tablo alaninin degerini aktariyoruz.*/

              for(int i=0;i<PROPINFOS.LENGTH;++I)
              {
                   if(propInfos[i].CanWrite) /* Burada özelligimizin bir Set bloguna sahip olup olmadigina bakiliyor. Yani özelligimizen yazilabilir olup olmadigina. Bunu saglayan özelligimiz CanWrite. Eger özellik yazilabilir ise (yada baska bir deyisle readonly degil ise) true degerini döndürür.*/
                   {
                        try
                        {
                             if(dr[propInfos[i].Name]!=null) /* dataRow degiskeninde, özelligimin adindaki alanin degerine bakiliyor. Null deger degil ise SetValue ile alanin degeri özelligimize yazdiriliyor. */
                             {
                                  propInfos[i].SetValue(this,dr[propInfos[i].Name],null);
                             }
                             else
                             {
                                  propInfos[i].SetValue(this,null,null);
                             }
                        }
                        catch
                        {
                             propInfos[i].SetValue(this,null,null);
                        }
                   }
              }

         }
    }

     /* KitapKoleksiyonu sinifimiz bir koleksiyon olucak ve tablomuzdan alacagimiz iki alana ait verileri Kitap isimli nesnelerde saklanmasini sagliyacak. Bu nedenle, bir CollectionBase sinifindan türetildi. Böylece sinifimiz içinde indeksleyiciler kullanabilecegiz.*/

         public class KitapKoleksiyonu:System.Collections.CollectionBase
         {
              public KitapKoleksiyonu()
              {
                   SqlConnection conFriends=new SqlConnection(“data source=localhost;initial catalog=Friends;integrated security=sspi”);
                   SqlDataAdapter da=new SqlDataAdapter(“Select Adi,BasimEvi From Kitaplar”,conFriends);
                   DataTable dtKitap=new DataTable();
                   da.Fill(dtKitap);
         
                   foreach(DataRow drow in dtKitap.Rows)
                   {
                        this.InnerList.Add(new Kitap(drow));
                   }
              }

              public virtual void Add(Kitap _kitap)
              {
                   this.List.Add(_kitap);
              }
         
              public virtual Kitap this[int Index]
              {
                   get
                   {
                        return (Kitap)this.List[Index];
                   }
              }
         }
}

Ve işte formumuzda kullandığımız tek satırlık kod; 

private void btnDoldur_Click(object sender, System.EventArgs e)
{
     dataGrid1.DataSource = new ReflectDoldur.KitapKoleksiyonu();
}

Şimdi uygulamamızı çalıştıralım ve bakalım. 


Şekil 4. Programın Çalışmasının Sonucu
 

Görüldüğü gibi tablomuzdaki iki Alana ait veriler yazdığımız KitapKoleksiyonu sınıfı yardımıyla, her biri Kitap tipinde bir nesne alan koleksyionumuza eklenmiş ve bu sonuçlarda dataGrid kontrolümüze bağlanmıştır. Siz bu örneği dahada iyi bir şekilde geliştirebilirisiniz. Umuyorumki bu örnekte yapmak istediğimizi anlamışsınızdır. Yansıma tekniğini bu kod içinde kısa bir yerde kullandık. Sınıfın özelliklerinin isminin, tablodaki alanların ismi ile aynı olup olmadığını ve aynı iseler yazılabilir olup olmadıklarını öğrenmekte kullandık.  

Değerli Okurlarım. Geldik bir makalemizin daha sonuna. Hepinize mutlu günler dilerim.

tuna

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir