Merhaba,
Bugün Object sınıfına ait GetHashCode metodu ile ilgili bilgi vermek istiyorum. Bu metodun tanımları :
//Delphi: function GetHashCode(): Integer; overload; virtual; //C++: public: virtual int GetHashCode();
Objenin hash kodunu döndürür ki bu da objeye karşılık gelen sayısal bir değerdir ve hash tablosu mantığında objeye erişimi hızlandırmak amacıyla böyle sayısal değerler kullanılır.
GetHashCode fonksiyonunun mevcut hali, her bir obje için farklı değerler döndürmeyi garantilemez. Farklı sınıflara ait objeler mutlaka farklı hash kodlara sahiptirler, ama aynı sınıfa ait farklı nesneler aynı hash kodu taşıyor olabilirler. Yani hash kodu farklı iki nesne farklıdır ama bunun tersi doğru değildir. Bu yüzden eğer eşitlik karşılaştırması için kullanılacaksa bu metot, sizin sınıf yapınızda ezilmiş olmalıdır.
Ayrıca mevcut haliyle GetHashCode fonksiyonu, objenin içeriği değiştikçe farklı farklı değerler döndürüyor ve mesela içini boşalttığımız bir objenin hash kodu farklı dönerken, daha önce verdiğimiz bir değerin aynısını verirsek yine aynı hash kod dönüyor. Farklı objelerde de bu aynı şekilde oluyor, yani bu durumda her değer tek bir hash koda sahipmiş gibi sanki. Dolayısıyla aynı içeriğe sahip iki farklı obje aynı hash kodu döndürüyor. Şimdi aşağıdaki kodda bunu görelim (hash kod değerleri satır sonundadır) :
var
obj1 : &Object;
obj2 : &Object;
begin
obj1 := &Object.Create;
obj2 := &Object.Create;
ShowMessage('code1 : '+inttostr(obj1.GetHashCode)); //code1 : 18
ShowMessage('code2 : '+inttostr(obj2.GetHashCode)); //code2 : 23
obj1 := 'aa';
obj2 := 'ab';
ShowMessage('code1 : '+inttostr(obj1.GetHashCode)); //code1 : 5860901
ShowMessage('code2 : '+inttostr(obj2.GetHashCode)); //code2 : 5860902
obj2 := obj1;
ShowMessage('code1 : '+inttostr(obj1.GetHashCode)); //code1 : 5860901
ShowMessage('code2 : '+inttostr(obj2.GetHashCode)); //code2 : 5860901
obj1 := NULL;
obj2 := NULL;
ShowMessage('code1 : '+inttostr(obj1.GetHashCode)); //code1 : 39
ShowMessage('code2 : '+inttostr(obj2.GetHashCode)); //code2 : 39
obj1 := 'ab';
obj2 := 'aa';
ShowMessage('code1 : '+inttostr(obj1.GetHashCode)); //code1 : 5860902
ShowMessage('code2 : '+inttostr(obj2.GetHashCode)); //code2 : 5860901
end;
Bu haliyle fonksiyonumuz çok kullanışlı sayılmaz değil mi..
Aşağıda da klasik bir sınıf-öğrenci örneği için GetHashCode fonksiyonun ezilmiş hali var. Burada iki objenin eşit olabilmesi için hem sınıf hem de numara değerlerinin aynı olması gerekir. Dolayısıyla sadece sınıf bazında numaraların tekliğinin sağlanmış olması yeterlidir.
TMyClass = class(System.&Object)
public
adi : string;
soyadi : string;
numara : integer;
sinif : integer;
Function GetHashCode : integer; override;
end;
Function TMyClass.GetHashCode : integer;
begin
Result := strtoint(inttostr(sinif)+inttostr(numara));
end;
var
a1 : TMyClass;
a2 : TMyClass;
begin
a1 := TMyClass.Create;
a2 := TMyClass.Create;
a1.adi := 'Ali';
a1.numara := 15;
a1.sinif := 2;
a2.adi := 'Veli';
a2.numara := 15;
a2.sinif := 3;
ShowMessage('code1 : '+inttostr(a1.GetHashCode));
ShowMessage('code2 : '+inttostr(a2.GetHashCode));
if (a1.GetHashCode = a2.GetHashCode) then
ShowMessage('eşit!!');
end;
Bu arada Tuğrul’a da teşekkür etmek istiyorum. Bana kalsa hep erteleyip duracaktım bu dotNET öğrenme işini. Hepimizin böyle motivasyonlara ihtiyacı var silkinip harekete geçmek için galiba. Ama bundan fayda görecek ya da göremeyecek olan da sadece biziz aslında…
İyi çalışmalar
Nihal Pehlivan

Entries (RSS)
June 14th, 2006 at 10:03:22
güzel bir makale olmuş öncelikle:
ben pek fazla hakim değilim oop konularına
sınıfların eşitliklerini ancak bu şekilde mi kontrol edebiliriz.
yani;
–if (sınıf_1=sınıf_2)– şeklinde kullanım olmaz mı?
illaki –if (sınıf_1.GetHashCode=sınıf_2.GetHashCode)– şeklinde mi olmalı.