|
Karşılaştırılabilir/Sıralanabilir Nesneler 2 - IComparer |
|
Gönderiliyor lütfen bekleyin... |
|
|
.Net çatısı altında, bir dizi yada bir koleksiyon
içerisindeki nesneleri sıralamanın yolunun, bu nesnelerin IComparable arayüzünü
uygulamasından geçmesi gerektiğini geçen bölümde incelemiştik. Ancak sonucu
yakından incelediğimizde, bu sıralamanın tek bir üye üzerinde ve tek yönlü
olduğunu tespit etmiştik. Yani sınıfımızın iki örneği üzerindeki karşılaştırma
sadece Model değerleri göz önünde bulundurularak yapılır ve sıralama küçükten
büyüğe doğru olacaktır.
Peki belirli bir sınıftan iki nesnenin karşılaştırılması
sadece bu nesnelerin daha önce uygulamış oldukları IComparable.CompareTo() ya
bağlı mı kalacak? Ya bu nesneler dizisi üzerinde farklı bir sıralama yapmamız
gerekirse?
.Net çatısı bu probleme yine bir arayüzün uygulanmasıyla
çözüm getiriyor: IComparer. Otomobil sınıfımıza yeniden bir göz atalım. Elimizde
Model bilgisine göre, büyükten küçüğe sıralanabilir bir sınıf var.
/********************************************************************
*
* OTOMOBİL SINIFI
*
********************************************************************/
class Otomobil
{
// sınıfımızın parametreli yapıcı metodu...
public Otomobil(string marka, int model, string renk)
{
this.marka=marka;
this.model=model;
this.renk=renk;
}
//Property değerlerini tutacak yerel değişkenler
protected int model;
protected string marka;
protected string renk;
//Sınıfımızın property leri
public int Model // Model property
{
get{return model;}
set{model=value;}
}
public string Marka //Marka property
{
get{return marka;}
set{marka=value;}
}
public string Renk // Renk property
{
get{return renk;}
set{renk=value;}
}
public override string ToString()
{
return marka + "(" + model.ToString() + "-" + renk + ")";
}
public int CompareTo(object obj)
{
if(obj==null)// null durumunda diğer sıralamalardan önce gelir.
return 1;
// Gelen nesnenin tipi otomobil değilse hata meydana gelir.
Otomobil outer=obj as Otomobil;
if(outer==null)
throw new ArgumentException();
if(this.model>outer.model)
return 1;
else if(this.model<outer.model)
return -1;
else return 0;
}
}// end of class: Otomobil
|
Şimdi bu sınıfın karşılaştırma dolayısıyla sıralama
mekanizmasının çalışmasına bir göz gezdirelim. Aşağıdaki test programını
çalıştıralım.
/********************************************************************
*
* OTOMOBİL KOLEKSİYONU TEST KODU
*
********************************************************************/
// Dizi yapılandırılıyor...
System.Collections.ArrayList otomobiller;
otomobiller=new System.Collections.ArrayList();
// Diziye elemanlar ekleniyor...
otomobiller.Add(new Otomobil("Mercedes",2004,"Beyaz"));
otomobiller.Add(new Otomobil("BMW",2003,"Siyah"));
otomobiller.Add(new Otomobil("Opel",2002,"Kırmızı"));
otomobiller.Add(new Otomobil("Honda",2000,"Mavi"));
// Dizi elemanları sıralanıyor
otomobiller.Sort();
//Dizi döngüye alınarak elemanları ekrana
yazdırılıyor...
for(int i=0;i<otomobiller.Count;i++)
{
Console.WriteLine("{0}. otomobil : {1}",i,otomobiller[i]);
}
Console.Write("Programı sonlandırmak için [ENTER] tuşuna basın.");
Console.ReadLine();
|
Sonuçta ekran görüntüsünde otomobillerin Model bilgilerine
göre küçükten büyüğe doğru sıralandığını görürüz. Zaten bu sonuç CompareTo()
metodunun amaçladığı bir sonuçtur ve sınıfın doğal karşılaştırma/sıralama
davranışı budur.
Şekil 1: Otomobil sınıfının doğal sıralama
sonucu
Diyelim ki otomobil sınıfı elimizde kod olarak yok da, hazır
bir dll içinde var. Doğal olarak artık koda müdahale edemediğimizden,
IComparable.CompareTo() metodunda da değişiklik yapamayız. Ama uygulamamızın bir
yerinde otomobilleri Marka bilgilerine göre sıralamamız gerekirse ne yapacağız?
Böyle bir durumda .Net yorumcusuna yeni bir karşılaştırma
yöntemi göstermemiz gerekir. .Net çatısı buna şu şekilde izin verir.
Adım 1: Öncelikle System.Collections.IComparer arayüzünü
uygulayan bir sınıf yazmamız gerekmektedir. class
OtomobilMarkaKarsilastirici:System.Collections.IComparer { ... } |
Adım 2: System.Collections.IComparer arayüzünün tek üyesi olan
Compare() metodunu uygularız.
public int Compare(object x, object y) {
... } |
System.Collections.IComparer.Compare() metodu,
System.IComparable.CompareTo() metoduna çok benzer. Dönüş değeri olara yine 0,
-1 ve +1 değerlendirilir. Ancak bu sefer iki parametre alır. Sonuçta
- x nesnesi (object x), y nesnesinden
(object y) büyükse +1
- x nesnesi (object x), y nesnesinden (object y)
küçükse -1
- x nesnesi (object x), y nesnesine (object y) eşitse 0
(sıfır)
değeri döndürülmelidir. Bunu gerçekleştirecek kodla birlikte
OtomobilMarkaKarsilastirici sınıfımızın son durumu şöyle olacaktır:
/********************************************************************
*
* OTOMOBİL KARŞILAŞTIRICI SINIF KODU
*
********************************************************************/
class OtomobilMarkaKarsilastirici:System.Collections.IComparer
{
public int Compare(object x, object y)
{
Otomobil xOto=x as Otomobil;
Otomobil yOto=y as Otomobil;
if(xOto==null || yOto==null)
throw new InvalidCastException("Hatalı
parametre");
// Marka bilgileri string sınıfıyla gelen
// CompareTo() metoduyla gerçekleştiriliyor.
return xOto.Marka.CompareTo(yOto.Marka);
}
}// end of class : OtomobilMarkaKarsilastirici
|
Şimdi test programında tek yapmamız gereken, otomobiller
listesini ekrana yazdırmadan önce sıralamak için kullandığımız kodun üzerinde
ufak bir değişiklikten ibarettir:
// Dizi elemanları sıralanıyor
otomobiller.Sort() |
yerine
//Dizi elemanları markalarına göre sıralanıyor
otomobiller.Sort(new OtomobilMarkaKarsilastirici()); |
.Net çatısıyla gelen System.Collections.IComparer arayüzünü
uygulayarak, yerleşik türler (built-in classes) de dahil olmak üzere tüm
sınıflar üzerinde dilediğimiz sıralama yöntemini uygulayabiliriz.
Ne demişler: Her şeyin bir şeyi var!
Makale:
Karşılaştırılabilir/Sıralanabilir Nesneler 2 - IComparer C#, Visual C# ve .NET Kadir Çamoğlu
|
|
|
-
-
Eklenen Son 10
-
Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
|
|