Makale Özeti

Makalemiz boyunca oluşturduğumuz bir tip üzerinde işlemler yapıcağız ve bu tipimizi bir koleksiyona alacağız . Aslında Generic hayatımıza girdiği zaman bu şekilde uygulamalar yavaş yavaş kullanılmamaya başlanmıştır. Ama biz generic koleksiyonlara makalemizin sonunda yer vericeğiz .Generic olmadığını düşünün nasıl yapardık .

Makale

Güvenli Koleksiyon Yazmak

Makalemiz boyunca oluşturduğumuz bir tip üzerinde işlemler yapıcağız ve bu tipimizi bir koleksiyona alacağız . Aldığımız bu koleksiyon sadece bizim tipimizden veya tipimizden kalıt ılmıs tipleri barındırabilsin ile güvenli olarak saklayacağız.

Aslında Generic hayatımıza girdiği zaman bu şekilde uygulamalar yavaş yavaş kullanılmamaya başlanmıştır. Ama biz generic koleksiyonlara makalemizin sonunda yer vericeğiz . Generic olmadığını düşünün nasıl yapardık …

Bu şekilde generic mantığının bize sunduğu avantajlarıda biraz öğrenmiş olacağız .
Aynı zamanda oluşturduğumuz tip içerisinde for ve foreach ile dönmeye çalışırken neler yapmamız gerektiğini de uygulamış olcağız.

Simdi Urun tipini oluşturalım bu urun tipimizin içerisinde adi fiyati serinumarasi seklinde bilgiler ve tostring ezilmiş bir bilgi ver metodumuz olsun.

 

namespace OrnekKod
{

class Urun
{

string _adi;
double _fiyat, _serino;

public string Adi { get { return this._adi; } set { this._adi = value; } }
public double Fiyat { get { return this._fiyat; } set { this._fiyat = value; } }
public double SeriNo { get { return this._serino; } set { this._serino = value; } }

public Urun(string ad, double fiyat , double serino)
{

this.Adi = ad;
this.Fiyat = fiyat;
this.SeriNo = serino;

}



public override string ToString()
{


return string.Format("Adı : {0} \n Seri Numarası {1} \n Fiyatı : {2}",
this.Adi, this.SeriNo, this.Fiyat);

}

}
}



Seklinde urun tipimizi olusturduk . Oluşturduğumuz bu urun tipimizin içerisinde yukarı dada yazdığımız gibi adi fiyati ve serino adında bilgiler yer almaktadır ve tipimizin bir yapıcı metot u birde tostring ezilmiş bilgi ver metodu vardır. Tip içerisinde değişkenlerimizi private ile tanımlayıp get ve set blokları ile kapsüllenmistir.

Simdi Dvd sınıfımızı yazalım ve urun sınıfından kalıtalım . elimizde gireceğimiz iki farkı tip olsun . Urun ve Dvd adında. Dvd tipimizi aşağıdaki gibi tanımladık.

namespace OrnekKod
{

class Dvd : Urun
{

int _kapasitesi;

public int Kapasitesi { get { return this._kapasitesi;} set { this._kapasitesi = value; } }

public Dvd(string ad , double fiyat , double serino, int kapasite) : base(ad,fiyat,serino)

{

this.Kapasitesi = kapasite;

}

public override string ToString()
{

return base.ToString() + " \n Kapasitesi " + Kapasitesi;

}
}
}




Yukarıdaki şekilde dvd sınıfımızı urun tipinden kalıtarak tanımladık ve ek olarak kapasite değerini aldık . kalıtım aşamasında yani dvd yapıcı metodunda kapasitesi haricindeki bilgileri iki farklı şekilde yazabiliriz . istersek yukarda bizim kullandığımız gibi base(base class parametreleri ) seklinde yapıcı metodumuz ile birlikte kullanabilir. veya yapıcı metodumuzun gövdesinde base.adi = adi ; seklinde tanımlayabiliriz . base anahtar sözcüğü bir alt sınıf da olan yani bu sınıfa kalıtılan anlamına gelmektedir . this anahtar söz dizimi de bu tip ( class ) için geçerli olan anlamındadır.

Bu asamaya kadar iki adet tip üretip urun ve dvd adında dvd tipimizi urun tipimizden kalıttık simdi bunları bir koleksiyona (ArrayList) bağlayalım . Örneğimizde ArrayList i kullanmak için aldık dediğimiz gibi belki arraylist artık kullanılmıyor ama gelişen yeni teknolojileri daha iyi takip edebilmek için o teknolojinin tarihini bilmemiz gerekir . Ado.net ogrenmeden Linq geçersek belki kod yazarız ama geliştirme ve mantığı acısından herhangi bir problemde ana çalışma mantığını bilmediğimiz için çoğu yerde takılırız.

Simdi Guvenlikoleksiyon sınıfımızı yazmadan önce genel bir mantığına bakalım nasıl olmalı Arraylist koleksiyonumuz içerisine object tipinden herse yi alabiliyor ve biz buna nasıl bir kontrol getirmeliyiz ki koleksiyonumuz içerisinde sadece urun tipi veya urun tipinden kalıtılmıs tiplerimiz olsun .

Private ArrayList Urunlistesi; seklinde dışarıdan erişilmeyen ama içeride kullanabildiğimiz bir koleksiyon tasarlasak ve bunu dış dünyaya kontrollü açsak nasıl olur ?
Sorumuzun generic olmadan çözümü ebetteki bu şekilde olacaktır. Koleksiyonumuzu private olarak oluşturup dış dünyaya kontrollü bir şekilde acıcağız . simdi isterseniz güvenli koleksiyon sınıfımızı tanımlayalım .

class GuvenlyList : IEnumerable
{
private ArrayList UrunListesi
;


Yukarıdaki tanımlamada bir tip içerisine yeni bir arraylist tanımladık buradaki ana amaç arraylist imiz içerden private tanımlayıp dış dünyaya kontrollü açmak olacaktır. Normal şartlarda arraylist imiz object tipinden her şeyi kabul eder ama biz dış dünyaya kontrollü bir şekilde açtığımız için bizim tipimizi kullanan her yordam değer olarak urun tipinden urun girmek zorunda bırakıcağız. İlk önce defaulr cons. Yapıcı metot umuzu tanımlayalım ve iki adet tanımlayıp yapıcı metodumuza aşırı yüklenelim .

İlk tanımlamamızda normal parametre almayan bir ctor tanımlıyoruz ve içerden arraylist imizim normal bir şekilde oluşturuyoruz.

public GuvenlyList()
{
UrunListesi = new ArrayList();
}

Yukarıdaki tanımlama örneklenir ise arraylist imiz default değerleri ile örneklenmiş olacaktır. Peki örnekleme zamanında oluşturacağımız listemizin ilk kapasitesini biz belirlemek istiyoruz yapmamız gereken tek şey default ctor aşırı yüklenip int tipinden bir kapasite değeri almak yeterli olacaktır.

public GuvenlyList(int kapasite)
{
UrunListesi = new ArrayList(kapasite);
}

Seklinde bir tanımlama ile int tipinden bir deger aldık ve bu degeri arraylist imizin (kapasite) olarak belirledik ve ilk başlangıç aşamasındaki değerini belirledik .

Buraya kadar güvenli tipimizi oluşturduk ama içine herhangi bir değer almadık. simdi bir metot yazalım ve ana amacımız olan urun ve urunden kalıtılan değerleri alacak bir metot yazalım.

public void UrunEkle(Urun Urunal)
{
UrunListesi.Add(Urunal);
}

Tanımladığımız metot parametre olarak Urun tipinde urunal istemektedir . arraylist imizi dış dünyaya kontrollü açtığımız için bizim belirlediğimiz değerler arraylistimize tanımlanacaktır . Artık UrunEkle metodu sayesinde içerde tanımladığımız arraylist imize sadece urun ve urunden kalıtılmıs sınıfları barındırır .

Ama unutulmaması gereken bir nokta biz burada sadece dışardan gelen değerleri filtreledik arraylist bunları kendi içinde yine object tipinden tutar ve boxing unboxing işlemleri ile bize tekrar geri verir. Bizim amacımız dış tarardan müdahaleyi kontrol altına almak adına idi …

Örnek kodlarımız arasında Arraylist in bazı metotlarında yukarıdaki gibi dış dünyaya açılmıştır. Kısaca belirtmek gerekir ise.

Urun Cıkart
Kapasite Goruntule
Mevcut Urun
Kapasite Mevcut Urune Esitle

İşlemleri de bizim tanımladığımız public metotlar ile dış dünyaya kontrollü bir şekilde açılmıştır.

Buraya kadar her şey çok normal bir şekilde oldu listemizi oluşturduk ekledik çıkarttık ve diğer parametrelerini isleme tabii tuttuk. Peki bunları ekrana yazdıralım for ve foreach iterasyonlarını kullanarak ?

Kendi yazdığımız bir tip içerisinde for ve foreach iterasyonlarını kullanmak için bize neler gerekli .

public static void ListeleFor(GuvenlyList ListAl)

{

ListAl.KapasiteCountEsitle();
for (int i = 0; i < ListAl.KapasiteGoruntule(); i++)
{

Console.WriteLine(ListAl[i].ToString());

}
}

Yukarıdaki şekilde bir for döngüsü kurduğumuz zaman for i . değeri kadar dönecek ve ListAl[i] değerini ekrana bastıracaktır . Direk olarak yazar isek for döngümüz çalışmayacaktır. Ve bizden indexer tanımlaması isteyecektir. indexer tanımlamaları nedir .

İnt[] sayilarim = new int [3]; seklinde bir dizi belirlediğimiz zaman
Sayılarım[i] bura i 0 . elemanı anlamına gelir bizde for döngümüzde bu şekildeki mantığını kullanarak i değerine eşit gelen urun bilgisini alacağımız için indexer tanımladık .

public object this[int sayac]
{
get { return this.UrunListesi[sayac]; }
set { this.UrunListesi[sayac] = value; }
}

Yukarıdaki şekilde indexer belirlemiş olduk int sayaç bizim for döngümüzde i değerine sayı verecektir. get blokları içerisindeki tanımlamaya bakar isek return this.UrunListesi[sayac] yani inci değeri anlamında bize geri dondurur .

Bu tanımlamayı güvenli list class imiz içerisinde oluşturur isek artık güvenli list imiz içerisinde for döngüsü ile dönebiliriz.

Simdi IEnumerable interface imizi tipimize implement edelim ve bu interface in içerisindeki GetEnumerator metodunu kullanalım aşağıdaki gibi .

public IEnumerator GetEnumerator()
{
return UrunListesi.GetEnumerator();
}

Tek yapmamız gereken return UrunListesi.GetEnumerator(); kısmını tanımlamak olacaktır . Simdi foreach iterasyonunu kullanarak da tipimiz içerisinde dönebiliriz.

Yukarıdaki tanımlamada generic öncesinde güvenli tiplerimizi nasıl tanımladığımızı anlattık ama artık hayatımızda generic var ve sadece

List<T> seklinde güvenli tiplerimizi belirleyebiliyoruz . Benim şahsi olan düşüncem ilk önce mantığını anlamak daha sonra günün teknolojisi neyi gerektiriyor ise onu kullanmaktan yanadır.



Yandaki tanımlamada list<urun> YeniUrunlistesi = new UrunListesi();
YeniUrunlistesi.add(

Seklinde bir tanımlama yaptığımız zaman bizden direk olarak urun tipinden item istemektedir . Generic koleksiyonlar ile artık makale boyunca yazdığımız şekilde bir tanımlama kullanılmaz. List generic ler ebetteki normal bizim tanımladığımız güvenli koleksiyonlardan daha kullanışlı ve daha hızlıdır . object tipinden al daha sonra unboxing yap gibi uğrası bize yaptırmaz kendi içinde generic olarak bizim tanımladığımız tip de tutar ve hiç bizi yormadan bilgiyi geri verir .

 



Ornek