Generic nedir: Bir listeye, liste elemanı olacak şeyin (değişken, nesne ve her neyse) tipini vererek, liste içinde yapılan tüm işlemlerin bu tipe göre yapılmasını sağlayabilen listelerdir.
Örnek verirsek, önce bir Console projesi yaratalım. Sonra aşağıdaki kodları yazalım
program Project1; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.Generics.Collections; var tamsayiliste : TList<Integer>; i : integer; begin tamsayiliste := TList<Integer>.Create; tamsayiliste.Add(181); tamsayiliste.Add(22); tamsayiliste.Add(11); tamsayiliste.Add(17); for i in tamsayiliste do WriteLn(i); ReadLn; end.
Bunu çalıştırdığımızda sırayla eklediğimiz rakamları yazacaktır. Bu listeye farklı tipte bir eleman eklemeye çalıştığımızda derleme esnasında hata verecektir. Bu da bize büyük esneklik sağlayan bir gereç veriyor.
Bize ne sağlar: Her ayrı tip için ayrı bir liste sınıfı yazmamız gerekiyordu.
Önceden TList kullandığımızda elemenın tipi Pointer idi. Haliyle bunu şu şekilde yapıyorduk;
program Project1; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.Generics.Collections; var lst : TList; i : integer; begin lst := TList.Create; lst.Add(Pointer(181)); lst.Add(Pointer(22)); lst.Add(Pointer(11)); lst.Add(Pointer(17)); for i:=0 to lst.Count-1 do WriteLn(IntToStr(Integer(lst[i]))); ReadLn; end.
Eğer string'lerden oluşan bir liste istiyorsak TStringList'i kullanmak ya da TList'i değiştirmek gerekiyordu. Şimdi ise bunlara hiç gerek kalmadı. Yapmamız gereken sadece;
program Project1; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.Generics.Collections; var lstr : TList<string>; s : string; begin lstr := TList<string>.Create; lstr.Add('Ahmet'); lstr.Add('okula'); lstr.Add('gelecek,'); lstr.Add('ama yarın...'); for s in lstr do Write(s+' '); ReadLn; end.
Bu listeye string'den başka bir tip eklemeye kalksak bize hata verecektir. Bu da bize, üst düzey dillerin çok önem verdiği ve önemli hata kaynaklarından biri olan, Type Safe (Tip Güvenliği)'ni sağlayacaktır. Yani bir tamsayı listesine başka bir tipte değişkeni eklememizi engelleyecektir.
Generic listeleri her tür class'lar için de kullanabiliriz.
program Project1; {$APPTYPE CONSOLE} {$R *.res}
uses System.SysUtils, System.Classes, System.Generics.Collections; type TContact = class ContactId : Integer; ContactName : string; BirthPlace : string; BirthDay : TDate; Gender : string; function ToString : string; override; constructor Create(aContactId : Integer; aContactName : String; aBirthPlace : String; aBirthDay : TDate; aGender : String); end; { TContact } constructor TContact.Create(aContactId: Integer; aContactName, aBirthPlace: String; aBirthDay: TDate; aGender: String); begin ContactId := aContactId; ContactName := aContactName; BirthPlace := aBirthPlace; BirthDay := aBirthDay; Gender := aGender; end; function TContact.ToString: string; begin result := IntToStr(ContactId)+'/'+ContactName+'/'+BirthPlace+'/'+DateToStr(BirthDay)+'/'+Gender; end; var MyContacts : TList<TContact>; fcon : TContact; begin MyContacts := TList<TContact>.Create; MyContacts.Add(TContact.Create(1, 'Ahmet Acar', 'Rize', EncodeDate(1977, 1, 10), 'Erkek')); MyContacts.Add(TContact.Create(2, 'Çoşkun Pireli', 'Artvin', EncodeDate(1992, 5, 3), 'Erkek')); MyContacts.Add(TContact.Create(3, 'Mehmet Kesmez', 'Bolu', EncodeDate(1983, 11, 27), 'Erkek')); MyContacts.Add(TContact.Create(4, 'Cahide Küskün', 'Eskişehir', EncodeDate(1996, 6, 12), 'Kadın')); for fcon in MyContacts do WriteLn(fcon.ToString); ReadLn; end.
Peki bu listeye farklı bir class eklemeye kalkarsak ne olur. Önce yukarıya şöyle bir sınıf tanımlayalım;
type TInvalidContact = class Id : Integer; Name : string; end;
daha sonra ise bunu listeye eklemeye çalışalım;
... ... MyContacts.Add(TInvalidContact.Create); ... ... ...
İşte Generic listin özelliği burada belli olacak. Bu satıra derleme hatası verecek ([dcc32 Error] Project1.dpr(nn): E2010 Incompatible types: 'TContact' and 'TInvalidContact'). Ve bu tür hatalar da bizi büyük hatalardan koruyacak!...
Blogunuzda Delphi ile ilgili çok güzel makaleler var. Bunların tümünü DelphiCan'da da yayınlayın bence. Böylece daha fazla kişi faydalanmış olur.
YanıtlaSil