1. Uvod u generičko programiranje
Pod pojmom Generički – misli se na neki opšti oblik, na nešto što nije specifično. Kada u C#-u sretnete pojam generički, to znači da se ne odnosi ni na jedan poseban tip podataka
Pod pojmom generičkog programiranja podrazumeva se izrada programskog koda koji se u nepromenjenom obliku može primeniti na različite tipove podataka.
Kako je to rađeno pre C#-a:
U programskom jeziku C - koristi se makro
U C jeziku se za generičko programiranje koriste predprocesorske makro naredbe, npr:
#define Kvadrat(x) x*x
Ovo je makro naredba kojom se deo koda koji je u zagradama označen sa x zamenjuje sa x*x. Makro naredbe nisu funkcije. One se realizuju u toku kompajliranja leksičkom zamenom teksta.
Primer:
| Makro naredba: | Izvršava se kao: |
|---|---|
|
int i;
Kvadrat(i) * 3 |
int i;
i*i*3 |
|
float x;
x*Kvadrat(6.7) |
float x;
x*6.7*6.7 |
|
float x;
x=Kvadrat(x+6.7) |
float x;
x=x+6.7*x+6.7 //greška |
U prva dva primera pokazano je kako se ista makro naredba koristi za tipove int i float. Greška u trećem primeru, se može izbeći tako da se „argumenti“ makro naredbe napišu u zagradama tj.
#define Kvadrat(x) (x)*(x)
Problem kod makroa je da je programski kod makroa nepregledan i teško je uočiti greške prilikom kompajliranja, budući da kompajler samo taj programski kod makroa nalepi umesto poziva i moguće su semantičke greške koje je vrlo teško otkriti.
U programskom jeziku C++ koristi se template (šablon):
U jeziku C++ pri definiciji funkcije moramo navesti tipove parametara. C++ dopušta korišćenje preopterećenih (overloaded) funkcija. To su funkcije koje imaju jednaka imena ali različitu listu parametara. Preopterećivanje funkcije ima nekoliko nedostataka: ukoliko želimo nešto promeniti u kodu funkcije moramo to učiniti na puno mesta, pa se povećava i mogućnost greške, ne možemo predvideti na kojim će sve tipovima korisnik hteti da pozove funkciju.
U C++ se isti efekat kao u C-u sa #define može postići korišćenjem definisanjem inline funkcija:
inline int Kvadrat(int x) {
return x*x;
}
inline float Kvadrat(float x) {
return x*x;
}
inline double Kvadrat(double x) {
return x*x;
}
Primetimo da sva tri tipa definicije funkcije Kvadrat imaju isti oblik:
T Kvadrat(T x) {
return x*x;
}
gde T može biti int, float ili double. Ova definicija ima generički oblik. U C++ jeziku se može vršiti generičko definisanje funkcija, na način da se ispred definicije ili deklaracije funkcije, pomoću ključne reči template, označi da T predstavlja „generički tip“.
template <typename T> T Kvadrat(T x) {
return x*x;
}
Izvršenje poziva funkcije se mora obaviti sa stvarnim tipovima:
int x,y; y=Kvadrat<int>(x);
Pogodno je da se klase i funkcije mogu pisati generički, parametrizovano tipovima podataka. Takve generičke klase i funkcije nazivaju se u jeziku C++ šablonima (templates). Iz šablona se generišu stvarne klase, odnosno funkcije, za konkretne tipove.
Generički mehanizam je u potpunosti statički - zamena parametara je u vreme prevođenja. Funkcijski šablon se ne koristi dok kompajler ne naiđe na poziv generičke funkcije. Tek tada se stvara i prevodi nova varijanta funkcije u zavisnosti o tipu na kojem
je funkcija pozvana.
A kako se to koristi u programskom jeziku C# :
U C#-u mogu da se definišu klase, interfejsi, apstraktne klase, polja, metode, statičke metode, propertiji, događaji, delegati i operatori korišćenjem type parametra, i bez navođenja konkretnog tipa podataka. Taj parametar će da dobije potrebni tip podataka kasnije, u programu, prilikom kreiranja konkretnog primerka (instance).
Generički tipovi se deklarišu tako što se navodi ime type parametar u šiljatim zagradama < >. Uobičajena praksa je da se između zagrada za tip koristi slovo T ukoliko se radi sa jednim parametrom ili da se koristi slovo T kao predznak poput TKey, TValue ukoliko se deklariše više parametara.
Na primer, ako se želi napraviti lista koristeći generičnost, moguća deklaracija bi bila List <T>, gde T predstavlja vrstu podataka. Kada se načini primerak može se napraviti List<Integer> ili List<Osoba>. Prema listi se zatim postupa kao prema listi onog tipa podataka koji je naveden.
(primeri koji se koriste na vežbama će biti postavljeni kasnije)