19 Haziran 2010 Cumartesi

Karsilastirilabilir Tipler Yazmak- CompareTo(IComparable)

Bazen elimizde olan verileri siralamak isteriz en basitinden. Bunu yaparken kullandigimiz komutlarin arka planda nasil calistiklarini bilmeyiz. Direk array.sort der geceriz, ama bilmeyiz ki gunun birinde elimizde siralanmasi mumkun olan ama ilk gorunuste siralanmayacak veriler olabilir. Iste o zaman fildir fildir nasil siralayacagiz bunlari diye nette arama yapariz, yada "ulan array.sort'un calisma mantigi ne acaba" diye sorariz. Kisaca bu sorunlara cozum bulmaya calisalim.

int[] sayilar = { 4, 5, 12, 6 }; //Amac: Sayilar dizisini artan siralamak.
Array.Sort(sayilar);

Iste yapmamiz gereken sadece tek satirda siralama yapan kodu cagirmak. Yazdigimiz kod da bunu yapiyor zaten, yapmamiz gereken sey siralanmis diziyi yazdirmak.
foreach (int s in sayilar)
{
Console.WriteLine(s);
}
Console.WriteLine("**********");

Ekran ciktisi su sekilde olacaktir.


Kodlari ILDisassambler ile inceledigimiz zaman aslinda array.sort dedigimiz zaman IComparable interfacesinin CompareTo metodunu calistirip orada gerekli islemlerle artan siralama yapiliyor. Peki bizim elimizde siralanamayacak turden veriler olursa, yani IComparable interfacesini implement eden bir nesne yoksa siralamayi nasil yapacagiz?

Elimizde su classlar oldugunu varsayalim;
Urun[] urunler = { new Urun(1, "Monitor", 200), new Urun(2, "Klavye", 80), new Urun(3, "Mouse", 100) };
Array.Sort(urunler);
Array.sort dedigimiz zaman urunler classini siralayamacagini goruyoruz. Bunun icin yapmamiz gereken sey bizim kendimiz CompareTo metodu olusturup, yazacagimiz class'i da IComparable interfacesinden implement etmemiz gerekecekti. Kisaca ustte yazdiklarimizi daha acik bir dille ozetlemek gerekirsek;
  • Sort metodu, gelen dizinin icinden belli bir siralama algoritmasi kullanarak, her defasinda iki elemani secer!
  • Bu iki elemani CompareTo metodundan gelen sonuca bakarak karsilastirir ve gelen sonuca gore elemanlari siralanmasini saglar.
  • Sort metodunun calisabilmesi icin gelen dizideki tum elemanlarin karsilatirilabilir tipler olmasi gerekmektedir.Yani Icomparable interface'ini implement etmesi gerekir.
O zaman kisaca biz ustteki urun dizisi icin bir CompareTo metodu yazalim. Bunun icin ustte de belirttigimiz gibi IComparable interfacesinin implement etmesi gerekecek.
class Urun:IComparable

public int CompareTo(object obj) //ArraySort metodu ile geldi buraya
{
Urun gelen = (Urun)obj;
if (Fiyat > gelen.Fiyat) return 1;
else if (Fiyat <>
else return 0;
}
1 , -1 ve 0 degerleri CompareTo metodunun kendi icinde bulunan algoritmadir. Bunu yine kendimize gore uygulayabilirdik.

Bu kodlamalardan sonra da yapmamiz gereken tek sey foreach ile dizide donup elemanlari ekrana yazdirmak.
foreach (Urun urn in urunler)
{
Console.WriteLine(urn);
}
Hemen ek bir bilgi daha verelim, ekrana biz urun ismi ve fiyatlari gostermek istiyorsak, yine ayni sekilde ToString metodunu override ederek object.ToString sinifini ezmis olur ve boylece kendimiz istedigimiz degerleri ekrana yazdirabiliriz. Yani;
public override string ToString()
{
return Ad+","+Fiyat;
}
Buna gore ekran ciktimiz asagidaki sekilde olacaktir.


0 yorum: