6. Definisanje nabrojivog i strukturnog tipa
Enumeracije ili nabrajanje tipa Enum u C# programskom jeziku
Enumerations
- enumeracije su specijalni vrednosni tipovi podataka koji omogućava da zadate
grupu imenovanih numeričkih konstanti. U Srbiji se enumeracija često naziva
nabrajanje, ali onda je bolje da kažete nabrajanje tipa enum jer postoje i
druge vrste nabrajanja u C# programskom jeziku.
enum ime_enumeracije
{
vrednost1; vrednost2; … }
enum ime_enumeracije
{
vrednost1 = 0; vrednost2 = 1; … }
Međutim ukoliko vi dodate neku vašu celobrojnu vrednost, posle nje će svaka vrednosti biti uvećana za 1. Npr.
enum ime_enumeracijeTo znači da je u ovom slučaju vrednost2 jednaka 2, sledeća vrednost bi imala vrednost 3 itd. Vi možete imati iste vrednosti u stavkama enumeracije ali ne vidim poentu zašto bi ste to radili. Enumeracije su po defaultu tipa integer ali vi možete to promeniti u drugi celobrojni tip podataka.
{
vrednost1 = 1; vrednost2; … }
enum ime_enumeracije : byte { ... }Strukture u C# programskom jeziku
Struktura se deklariše kao i enumeracija ili klasa, samo što koristi ključnu reč struct. Sintaksa strukture je:
Struct ime_strukture
{
članovi_strukture;
};
Članovi strukture mogu imati pored promenjivih i metode i čak konstruktore. Strukture jesu izvedene iz klase Object,
ali one ne mogu da vrše nasleđivanje. To u prevodu znači da struktura
ne može da sadrži druge strukture ili klase. Vi ne možete imati
konstruktor u strukturi koji ne uzima ni jedan parametar. On već postoji
i implicitno inicijalizuje na nulu sva polja u strukturi. Struktura ne
može da sadrži destruktor. Vi ne morate da koristite ključnu reč new da instacirate članove strukture ali nije zabranjeno. To takođe ne znači da ćete sa ključnom rečju new prebaciti deo memorije strukture sa steka na hip. Struktura se isključivo formira u stek segmentu.
*** Za one koji žele da znaju malo više: ***
Struktura jeste slična klasi ali nije klasa, koristi se slično
enumeracijama ali nije enumeracija jer nema nabrajanja. Najjednostavnije
rečeno, struktura vam je vrednosni tip podataka koji služi da
enkapsulirate manji skup podataka. Za razliku od klasa koji su
referentni tip i koji se kreiraju na hipu, strukture se kreiraju na
steku i sve dok je struktura mala, upravljanje memorijom koja upravlja
hipom je znatno smanjeno. Možete se pitati zašto je to bitno, zar sad
treba da razmišljate i o memoriji dok programirate. U principu uvek
treba u programiranju da razmišljate o memoriji bez obzira koliko je
imate u računaru. Da bi vam bilo jasnije, treba da znate da je memorija
računara definisana u tri segmenta. U tekst ili kod segment, stek
segment i hip segment.Razlika između Struct i Class u C# programskom jeziku
Često pitanje u OOP načinu programiranju jeste koja je zapravo razlika između strukture i klase.
Prvo ću krenuti sa strukturom, struktura u C# programskom jeziku je value type što znači da se njena alokacija se uvek nalazi na steku (stack).
Klasa za razliku od strukture svoju alokaciju ima na heap-u tj. u
dinamičkoj dijelu memorije, u potpuno drugom logičkom djelu memorije u
odnosu na stek.
U primeni, strukturu ćemo najčešće naći kada radimo sa manjim tipovima
podataka i manjim količinama podataka, glavni razlog ove "odluke" jeste
taj što ona uveliko utiče na performanse naše App (aplikacije). Ako se
vodimo predhodno naučenim pojmom čuvanja strukture na steku, imamo
pojavu da kada želimo poslati strukturu u neku od funkcija, mi zapravo
tada šaljemo čitavu strukturu i njen sadržaj. Iz ovog možemo zaključiti
da u runtime-u imamo proces kompletnog kopiranja objekta onoliko puta
koliko pozivamo funkcija koje kao parametar preuzimaju našu strukturu,
računica i zaključak je jednostavan: u slučaju veće strukture imamo
mnogo veće vreme izvršavanja koje uglavnom ide na kopiranje svih
informacije iz strukture u njenu lokalnu kopiju.
Važno za napomenuti je da je stek mnogo manja logička količina memorija u
odnosu na heap, i proces slanja strukture kroz funkcije duplo povećava
zauzeće memorije na steku. Još jedna bitna stvar je da u funkciji mi
radimo sa kopijom objekta koji je poslat pri pozivu funkcije i svaku
promenu koju želimo raditi moramo na adekvatan način uraditi i na
"glavnom" objektu.
Kada uzmemo u obzir čitav proces kopiranja shvatimo koliko je ovo
"skupo" za našu App... Ako ovaj isti primer primenimo na klase koje su reference type,
iz jednog mini testa koji ćemo uraditi u sledećim koracima...dolazimo
do zaključka da se klase uvek šalju po referenci tj. u funkciju koja
prima našu klasu mi šaljemo adresu našeg objekta u dinamičkoj memoriji i
samim tim mi nemamo potrebu za kopiranjem onoga što se nalazi u klasi, a
sa ugla performansi šaljemo mnogo manju informaciju (za razliku do
strukture i slanja čitavog objekta). Kada prosledimo adresu (referencu)
mi u funkciji direktno pristupamo toj memorijskoj lokaciji i radimo
potrebne izmene nad našim objektom.
Malo objašnjenje za predhodne pojmove u slučaju da nisu jasne stvari oko
adresa. Svaki vaš objekat koji je smešten u memoriji ima svoju
memorijsku adresu tj. lokaciju na kojoj se nalazi. Kada vi imate
informaciju tj. adresu na kojoj je vaš objekat vi imate "pravo" i
mogućnost da ga direktno editujete... mnogo će biti jasnije u sledećem
primeru:
Na slikama ispod vidite kako izgleda naša struktura pod imenom "TackaKoordinateStruktura", njeni atributi i konstruktor:

kao i kod na kojem je definisana naša klasa "TackaKoordinateKlasa", atributi i konstruktor:

Kao što i vidite skoro da su identične, jedina razlika na prvi pogled je u ključnim rečima class i struct. Ali naravno velika je razlika u pozadini, a to ćemo upravo dokazati na sledeći način:
Za potrebu ovoga mini testa koristit ćemo dve funkcije koje kao parametar primaju strukturu i klasu, naravno jedna prima strukturu, a druga klasu i izgledaju ovako;


Ako pokrenemo naš program možemo očekivati sledeći ispis na konzoli:

Ako pažljivo pratimo ispis na konzoli, možemo primetiti da se vrednost atributa naše strukture promeni samo u funkciji PromjenaStanjaStrukture(), kada se završila funkcija u mainu imamo informaciju da je vrednost atributa strukture ista kao i pre poziva. Iz ovoga možemo zaključiti samo jedno, da je naša struktura po svojoj prirodi poslata u funkciju po vrednosti i da smo u funkciji radili i vršili promene sa njenom kopijom koja je naravno uništena pri završetku funkcije (silazak sa steka).
Sa druge strane ako posmatramo ponašanje naše klase, pri inicijalizaciji je dobila vrednosti (7, 12), te u funkciji PromjenaStanjaKlase(), kao što je i definisano dobija vrednosti (20, 7), posle završetka sledi ispis koji nam ispisuje one vrednosti koje je klasa dobila u funkciji. Objašnjenje ovoga je da se klase uvek šalju po referenci, a ne po vrednosti kao što to strukture rade. Funkcija PromjenaStanjaKlase() dobila je adresu naše klase i mogla je direktno da utiče na promenu njenih atributa tj. modifikovali smo originalni objekat.
Iz ovog mini testa i primera dokazali smo i zaključili da se strukture uvijek šalju po vrednosti, a klase po referenci i ovo nam ujedno i govori pravu razliku između strukture i klase u C# programskom jeziku.
