Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

.Net i C# dileme...

[es] :: .NET :: .NET Desktop razvoj :: .Net i C# dileme...

[ Pregleda: 4142 | Odgovora: 15 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

_v!rus_
BGD

Član broj: 40451
Poruke: 313
*.dsl.siol.net.



+1 Profil

icon .Net i C# dileme...15.04.2006. u 23:41 - pre 225 meseci
Skoro sam presao na .Net i C#, imam par pitanja tehnicke prirode bez kojih ne mogu dalje da radim...

Naime,

1. Sobzirom da u .net-u ne postoje simple datatypes nego su sve Object descendant-i, kako se ovo kompajlira i radi bez greske?
Code:

int i = new int();
int j;

i = 3;
j = 4;

MessageBox.Show(i.ToString() + " " + j.ToString());

Ako je J objekat, kada se kreira?
Zasto ne radi kada su I i J Button-i (greska "Unassigned local variable J"), i zasto se ta greska ne javlja u datom primeru, kada je int umesto Button-a?




2. Ovo bi bio samo primer nekog generalnog principa koji pokusavam da shvatim:

Klasa TextBox ima property Font kome je dodeljena instanca klase Font. Klasa FontDialog takodje ima property Font kome je dodeljena instanca klase Font posle uspesnog izvrsavanja FontDialog.ShowDialog. Kako dodeliti sve osobine FontDialog.Font objektu TextBox.Font?

Ako napisem...
Code:

textBox1.Font = fontDialog1.Font;

...nece li se u objektu TextBox pointer Font samo preusmeriti da pokazuje na fontDialog.Font, odnosno nece li addressOf(textBox1.Font) biti jednaka addressOf(fontDialog1.Font)? Ocigledno da nece, jer stvar i dalje radi i posle sledece modifikacije:
Code:

textBox1.Font = fontDialog1.Font;
fontDialog1.Dispose();


Sto je jos cudnije, i posle fontDialog1.Dispose() i dalje se moze koristiti fontDialog1.ShowDialog iako ShowDialog nije static metod...


Moja prva ideja na temu je bila...
Code:

Font oldFont;

oldFont =  textBox1.Font;
textBox1.Font = (Font)fontDialog1.Font.Clone();
oldFont.Dispose();

...mada radi i sa...
Code:

textBox1.Font.Dispose;
textBox1.Font = (Font)fontDialog1.Font.Clone();

... i rade SVE iole smislene kombinacije datih primera BEZ GRESKE!


 
Odgovor na temu

NrmMyth
Ivan Maček
Split

Član broj: 63456
Poruke: 849
*.cmu.carnet.hr.

Sajt: www.dump.hr


Profil

icon Re: .Net i C# dileme...16.04.2006. u 01:16 - pre 225 meseci
1. Za sve najnize UGRADJENE tipove tipa [ int, string, double, decimal, char, ... ] nije potrebno exciplitno navoditi alokaciju/incijalizaciju sa 'new', tako su napravljeni da bi tebi bilo lakse.

2.
Code:
textBox1.Font = fontDialog1.Font;
Nisam gledao o cemu se ovdje radi, ali ako je Font struktura a ne klasa, onda se prenosi 'ByValue' i sve tvoje tvrdnje pobija. Vrlo je vjerojatno struktura...

Poz.
 
Odgovor na temu

_v!rus_
BGD

Član broj: 40451
Poruke: 313
*.dsl.siol.net.



+1 Profil

icon Re: .Net i C# dileme...16.04.2006. u 16:16 - pre 225 meseci
Ono sa prostim tipovima sam shvatio i hvala ti, jedino bih primetio da to možda malo ruši generičnost jezika sobzirom da ja ne mogu napisati klasu u c#-u koja će tako da se ponaša.

Što se tiče one druge stavke, to nisu moje "tvrdnje" nego su to moja "zapažanja", nemam ja nikakvog iskustva u C#-u da bih mogao da imam neke tvrdnje .
Prilično sam siguran da je Font klasa a ne struct posto se mora inicijalizovati sa new, za razliku od structa gde new samo poziva konstruktor, a i u MSDN-u piše da je klasa.
Na kraju krajeva, zato sam i postavio to pitanje, jer sam na sličnu situaciju naleteo par puta i ne znam kako se ona rešava po generalnom principu. U Delphi-u na primer, svi TObject descendant-i podrzavaju metod Assign koji omogucava kopiranje svih osobina sa jednog objekta na drugi objekat iste klase. U .Net-u čini mi se da clone() vrši sličan posao. Zato i pitam, da li se takva situacija u .Net-u (navedeni primer sa Font klasom) pravilno resava sa Clone() ili prostom dodelom...



[Ovu poruku je menjao _v!rus_ dana 16.04.2006. u 17:17 GMT+1]
 
Odgovor na temu

bunker
Srđan Savković
Smederevo

Član broj: 4495
Poruke: 239
212.200.27.*



Profil

icon Re: .Net i C# dileme...16.04.2006. u 21:07 - pre 225 meseci
Citat:
Sto je jos cudnije, i posle fontDialog1.Dispose() i dalje se moze koristiti fontDialog1.ShowDialog iako ShowDialog nije static metod...

Nije cudno. Kada si rekao fontDialog1.Dispose() ti nisi "otkacio" taj objekat, vecc si samo dao flag Garbage Collectoru da u sledeccoj akciji dealocira objekat fontDialog1. GC nije tako glup, pa ukapira iz sledeccih linija da se objekat ponovo koristi i zato preskace njegovu dealokaciju.
Dobrodosao u .net. Ovde se dealokacija objekata ne radi. To je potpuno automatski. Zahtev za resursima u startu je velik i kao programer si potpuno oslobodjen razmisljanja o unistavanju objekata.
Procitaj o garbage colletor-u:[url]http://msdn.microsoft.com/msdnmag/issues/1100/gci/[/url].

Object.Clone() u .net-u ne pravi deep clone objekta, vecc shallow copy, odnosno prenosi samo adresu objekta. Ne znam kako funkcionise ova funkcija u delfiju, lai u netu je sigurno shallow copy. Pogledaj sad ovaj primer:
Code:

this.fontDialog.Dispose();
this.lblFontPreview.Font = this.fontDialog.Font;
this.fontDialog = null;
this.lblFontName.Text = this.lblFontPreview.Font.Name;

Ako je lblFontPreview.Font bio shallow copy, pa je objekat dealociran, 4. linija vi trebalo da ne radi, ali ona funkcionise. Zato mislim da nisi bio u pravu sto se tice dela (Font)fontDialog1.Font.Clone(). Ovo se verovatno desava nekom drugom tehnikom. .

P.S. Trebalo bi da sam u pravu, ali nemoj potpuno da me drzis za rec. Na ovom forumu nije bilo dobrog pitanja duze vreme, pa nisam odoleoo da ne odgovorim. Naravno pozivam one koji misle da sam se izglupirao da iskomentarisu ovo kako v!rus i ja ne bismo ziveli u zabludi.

Nije važno stići prvi. Važno je prvo da stigneš.
 
Odgovor na temu

negyxo
Aleksandar Perkuchin

Član broj: 29751
Poruke: 898
*.sksyu.net.



+171 Profil

icon Re: .Net i C# dileme...17.04.2006. u 01:22 - pre 225 meseci
Nema mnogo filozofiranja. Reflector u ruke i sve ce vam se kasti
Code:

public sealed class Font : MarshalByRefObject, ICloneable, ISerializable, IDisposable

Odavde se lepo vidi da je upitanju klasa.

Code:

public object Clone()
{
      IntPtr ptr1 = IntPtr.Zero;
      int num1 = SafeNativeMethods.Gdip.GdipCloneFont(new HandleRef(this, this.nativeFont), out ptr1);
      if (num1 != 0)
      {
            throw SafeNativeMethods.Gdip.StatusException(num1);
      }
      return new Font(ptr1, this.gdiCharSet, this.gdiVerticalFont);
}

Sada je valda jasno da Clone vraca novu instancu.

Citat:

Ono sa prostim tipovima sam shvatio i hvala ti, jedino bih primetio da to možda malo ruši generičnost jezika sobzirom da ja ne mogu napisati klasu u c#-u koja će tako da se ponaša.

Ne razumem sta si ovime hteo da kazes. U kom smislu da se klasa tako ponasa? Koji je to slucaj kada se bez toga ne moze ili je samo pozeljno. Daj primer.

[Ovu poruku je menjao negyxo dana 17.04.2006. u 02:25 GMT+1]
 
Odgovor na temu

mmix
Miljan Mitrović
Chief Software Architect
Financial Intelligence Software Ltd.
Passau, Deutschland

SuperModerator
Član broj: 17944
Poruke: 6044



+4631 Profil

icon Re: .Net i C# dileme...17.04.2006. u 14:37 - pre 225 meseci
Citat:
_v!rus_: 1. Sobzirom da u .net-u ne postoje simple datatypes nego su sve Object descendant-i, kako se ovo kompajlira i radi bez greske?
Code:

int i = new int();
int j;
i = 3;
j = 4;


Mislim da ti niko gore nije konkretno ovo objasnio i rekao gde gresis. x i y ovde nisu objekti, i nije tacno da ne postoje simple types (ovde se zovu value types, nasuprot reference types). Int je value type i tvoje dve promenljive i i j su value types i alocirane su na steku.
Na tvoje sledece pitanje koje proizilazi iz ovoga (a kako onda radi int i = new int()?) odgovor je da kompajler "favorizuje" value tipove u smislu da ih ne tretira na isti nacin kao reference tipove. Svaki value type ima svoju referencu (to je bilo i pre, imas blok memorije gde je vrednost, adresa te lokacije je referenca). Pravilo je jednostavno, ako tip nasledjuje ValueType klasu onda referenca ne pokazuje na instancu klase nego na binarnu vrednost tog value tipa i ta referecna se koristi za. Konstruktor value tipova se nikad ne poziva nego kompajler alocira prostor shodno mestu gde je value tip definisan. Ono sto si ti uradio prvom linijom koda (pod uslovom da je optimizacija off) je da si kreirao trecu implicitnu promenljivu na steku i onda dodelio njenu vrednost u promenljivu i (a to je 0). posto se ta implicitna promenljiva nigde vise ne koristi, kompajler to jednostavno optimizuje u samo "int i;"

E sad, trece zbunjujuce pitanje, ako i i j nisu objekti kako mozes da pozoves metod ToString() nad njima. Odgovor je takodje u kompajleru i "favorizovanju". Ako je u pitanju pozivanje metoda nad value tipom, kompajler pronalazi metod asocirane klase i poziva ga kao da je metod objekta ali kao adresu objekta salje adresu binarne reprezentacije tipa. Nikakva mudrost stvarno, samo zbog "favorizovanja" odudara od OOP ponasanja i zato zbunjuje.
Kad su u pitanju value tipovi kompajler je potpuno "nasviran" i ima hard-coded ponasanje za svaki value tip, sto je izmedju ostalog razlog sto se ne mogu dodavati novi value tipovi (svaki pokusaj da nasledis ValueType klasu ce propasti), posto kompajler jednosavno ne bi znao sta da radi sa njim

Pogledaj ovaj clanak, http://blogs.msdn.com/jmstall/archive/2005/03/09/390135.aspx, za neke zanimljive primere poredjenja value tipova, boxovanju, implicitnoj konverziji, itd. Ako nista, zanimljivo je stivo.

Citat:
_v!rus_:
2. Ovo bi bio samo primer nekog generalnog principa koji pokusavam da shvatim:
Ako napisem...
Code:

textBox1.Font = fontDialog1.Font;

...nece li se u objektu TextBox pointer Font samo preusmeriti da pokazuje na fontDialog.Font, odnosno nece li addressOf(textBox1.Font) biti jednaka addressOf(fontDialog1.Font)? Ocigledno da nece, jer stvar i dalje radi i posle sledece modifikacije:
Code:

textBox1.Font = fontDialog1.Font;
fontDialog1.Dispose();

Sto je jos cudnije, i posle fontDialog1.Dispose() i dalje se moze koristiti fontDialog1.ShowDialog iako ShowDialog nije static metod...


Ok, da bi shvatio kako ovo radi konkretno, moras da se manes Delphi-a Taj nivo opreznosti sa internim stanjima objekata ovde vise ne pije vodu u vecini slucajeva, ukljucujuci i ovaj.

a) Da, pointer (referenca) Font ce se preusmeriti da pokazuje na istu instancu Font objekta, i da, addressOf ce biti isti. Ali to uopste nije problem, posto je GDI font u pozadini ove klase sasvim reusable u okviru istog thread-a. Ovde bi trebao da bude kraj tvojim mukama, ali kad hoces da znas zasto alternative takodje rade, ajmo dalje...
b) Klasa i dalje radi posle Dispose zato sto je:
b.1) Dispose samo dealocirao GDI Font u sistemu. Dispose ne unistava .NET objekat niti ga ubacuje na listu GC-a; .NET objekat je savim ziv i zdrav (mada sa unistenim GDI font-om, ali i dalje ziv), hvala na pitanju
b.2) Posto textBox1.Font pokazuje na isti objekat, i njegov interni GDI Font je (narafski) unisten.
b.3) Medjutim, .NET Font objekat je i dalje ziv i zdrav (vidi pod b.1). Cak i ako postavis fontDialog1 = null; ostace jedna "ziva" referenca u textBox1.Font i objekat nece otici pod "drobilicu" GC-a. Tek kad sve reference na objekat budu ili nullovane ili promenjene u drugu referencu ili odu out-of-scope tek tada instanca dolazi u pool da bude "zdrobljena".
b.4) [izmena, mala, reflektor mi je pokazao gde ja gresim, psoto sam konacno dosao do svoje radne stanice ]: texbox1 hoce da iskoristi svoj Font, iz Font objekta izvuce nativeFont GDI handle, koji je naravno IntPtr.Zero (0).
b.5) Ta nula dalje ode u Control.SetWindowFont() gde pukne i ne radi. Tako da moram da se ispravim i da kazem da nemam pojma zasto tvoj Font radi posle Dispose, probao sam i na vs2003 i na 2005 i ne radi. Bili poslao ceo sors forme?

Clone radi (on ionako kreira svoj GDI Font), tako da kao da si implicitno kreirao novi font i nisi pozvao Dispose na kraju . Cista dodela bez Dispose radi, posto se GDI Font nece unistiti dok ne dodje u GC pool. Jedino je problem kad se pozove Dispose nad objektom.

Ah, evo MSDN-u pise lepo:
Call Dispose when you are finished using the Font. The Dispose method leaves the Font in an unusable state. After calling Dispose, you must release all references to the Font so the garbage collector can reclaim the memory that the Font was occupying.

Znaci, ne pozivaj Dispose Moram priznati da sam malo razocaran u to kako je .NET resio ovo,

[Ovu poruku je menjao mmix dana 17.04.2006. u 16:12 GMT+1]
Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog
naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji
je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan,
sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv - Z.Đinđić
 
Odgovor na temu

mmix
Miljan Mitrović
Chief Software Architect
Financial Intelligence Software Ltd.
Passau, Deutschland

SuperModerator
Član broj: 17944
Poruke: 6044



+4631 Profil

icon Re: .Net i C# dileme...17.04.2006. u 15:52 - pre 225 meseci
Ok, sad vidim u cemu je fora, ti si radio Dispose na FontDialog formi, ne na njenom Font objektu. Posto je Dispose nasledjen od Component, Dialog.Dispose nije pozvao Dispose na Font objektu. U slucaju da nisi pokupio Font iz dialoga, u trenutku kad GC finalizuje dialog font ce biti postavljen na null i na kraju i sam biti unisten. Posto si ti pokupio referencu pre toga, GC je na kraju unistio Dialog ali je tvoj Font objekat ostao ziv i sa neunistenim GDI Fond handle-om. Trebalo je malo debagovanja, al to je to.
Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog
naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji
je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan,
sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv - Z.Đinđić
 
Odgovor na temu

Dragi Tata
Malo ispod Kanade

Član broj: 1958
Poruke: 3906
*.lionbridge.com.



+6 Profil

icon Re: .Net i C# dileme...17.04.2006. u 16:11 - pre 225 meseci
Citat:
bunker:
Dobrodosao u .net. Ovde se dealokacija objekata ne radi. To je potpuno automatski. Zahtev za resursima u startu je velik i kao programer si potpuno oslobodjen razmisljanja o unistavanju objekata.
Procitaj o garbage colletor-u:[url]http://msdn.microsoft.com/msdnmag/issues/1100/gci/[/url].


Nažalost, propagandna mašinerija MS-a i Sun-a (kad je u pitanju Java) navodi ljude da razmišljaju na ovaj način, ali to nije baš tačno.

GC brine o jednom jedinom resursu, a to je memorija. Dakle kad posmatramo memoriju, zaista ne moramo da brinemo kada ćemo da je oslobodimo. GC motri na potrošnju memorije i kad on nađe za shodno počistiće memoriju koju su zauzimali mrtvi objekti.

E sad, kao što se lepo vidi iz ovog slučaja, u realnom životu postoje i drugi resursi: fajlovi, db konekcije, socketi... GDI objekti. Klasa Font enkapsulira Font handle i kad kreiraš nov objekat klase font ti si alocirao ne samo memoriju za taj objekat, već i GDI handle. Kao što rekoh ranije, GC će da se stara o memoriji, ali za GDI handle si odgovoran ti kao programer i oslobodićeš ga tako što ćeš da pozoveš Dispose. Ako ne pozoveš Dispose, Finalizer će to da učini za tebe, ali tek u vreme kad GC reši da počisti memoriju, a to može da bude prekasno, jer i drugi resursi su ograničeni, a GC ih ne prati.

Dobar način da se gleda na ulogu Dispose funkcije je nešto kao destruktor u C++u. Posle pozivanja Dispose-a, objekat je mrtav; memorija koju zauzima još nije oslobođena ali to ne menja stvari: objekat je neupotrebljiv.

[Ovu poruku je menjao Dragi Tata dana 17.04.2006. u 17:12 GMT+1]
 
Odgovor na temu

NrmMyth
Ivan Maček
Split

Član broj: 63456
Poruke: 849
*.cmu.carnet.hr.

Sajt: www.dump.hr


Profil

icon Re: .Net i C# dileme...17.04.2006. u 20:40 - pre 225 meseci
bravo! :)
 
Odgovor na temu

_v!rus_
BGD

Član broj: 40451
Poruke: 313
*.dsl.siol.net.



+1 Profil

icon Re: .Net i C# dileme...17.04.2006. u 23:00 - pre 225 meseci
Prvo, hvala svima na strpljenju i odgovorima, po postavljanju teme i čekanju od cca 12 sati već sam pomislio da lupam gluposti...
Nije lako preći sa jednog alata na drugi, pogotovu kada krenu da ti se ruše svi principi za koje si mislio da su rock-solid...

Ajmo redom...

@negyxo:
Citat:

kompajler je potpuno "nasviran" i ima hard-coded ponasanje za svaki value tip...svaki pokusaj da nasledis ValueType klasu ce propasti

...e time sam mislio da se ruši "generičnost" jezika i frameworka čim hardkoduju kompajliranje za pojedine klase, mada mi ruku na srce zaista ne pada na pamet konkretan slučaj primene i kada bi bilo moguće napraviti svoj value tip. A i ta moja ideja je krenula od toga da su value types u stvari objekti, što se izgleda ispostavilo da je pogrešno. Na kraju krajeva, ništa bitno, samo 'nako, mislio sam da je neko najzad napravio generičan OO jezik, kada sam (pogrešno) pročitao da su simple types u stvari objekti.

@mmix
To da su svi simple(value) types u stvari objekti našao sam u Prof. C#, second edition (Wrox), pa sam shvatio zdravo za gotovo, tamo se ne pominju varijante sa "hard-coding"

Citat:

Ako je u pitanju pozivanje metoda nad value tipom, kompajler pronalazi metod asocirane klase i poziva ga kao da je metod objekta ali kao adresu objekta salje adresu binarne reprezentacije tipa

Ovo mi nije baš najjasnije (distinction between metod klase i metod objekta, metod klase = static metod?, kako inace radi kada je ref. tip?), ako imas vremena plz pojasni, baš bi hteo da ukapiram kako se to ispod haube dešava....

Citat:

textBox1.Font = fontDialog1.Font;
a) Da, pointer (referenca) Font ce se preusmeriti da pokazuje na istu instancu Font objekta, i da, addressOf ce biti isti. Ali to uopste nije problem...

Šta je u tom slučaju sa "originalnim" textBox1.Font? GC će ga zgazi jer je refCount=0?

I još par stvari, ako neko ima vremena, čisto rasprave radi:
1. Na osnovu postova ovde vidim da izgleda postoji jasna razlika između reference i pointera. Jel može neko to samo malo da pojasni?
2. Ako sam dobro shvatio Dragog Tatu, rule of thumb bi bilo: object.Dispose() koristimo kada nam ne treba dalji rad sa objektom, actual memorija biti oslobođena tek kada GC stupi na scenu. Posle poziva object.Dispose() postaviti object = null da mi obavimo naš deo posla, a nek' framework brine o eventualnim svojim referencama. Jel to OK?
 
Odgovor na temu

negyxo
Aleksandar Perkuchin

Član broj: 29751
Poruke: 898
*.sksyu.net.



+171 Profil

icon Re: .Net i C# dileme...18.04.2006. u 06:57 - pre 225 meseci
Hmm...

Citat:

Citat:

kompajler je potpuno "nasviran" i ima hard-coded ponasanje za svaki value tip...svaki pokusaj da nasledis ValueType klasu ce propasti

time sam mislio da se ruši "generičnost" jezika i frameworka čim hardkoduju kompajliranje za pojedine klase, mada mi ruku na srce zaista ne pada na pamet konkretan slučaj primene i kada bi bilo moguće napraviti svoj value tip. A i ta moja ideja je krenula od toga da su value types u stvari objekti, što se izgleda ispostavilo da je pogrešno. Na kraju krajeva, ništa bitno, samo 'nako, mislio sam da je neko najzad napravio generičan OO jezik, kada sam (pogrešno) pročitao da su simple types u stvari objekti.


Ma u redu je to sto su value tipovi hard coded ali jer to tebe sprecava da se ti sa njima odnosis kao sa objektima. To kako kompajler kompajlira ili bolje receno kamuflira taj objektni model tebe mnogo ne treba da zanima. Pitao sam te da navedes primer jer me interesuje kako bi ta klasa izgledala jer ja pretpostavljam da bi na kroju dosao do neceg za sta su strukture predvidjene da urade posao.

Citat:

1. Na osnovu postova ovde vidim da izgleda postoji jasna razlika između reference i pointera. Jel može neko to samo malo da pojasni?

Ja ti necu odgovoriti jer kontam javice se ljudi iz C/C++ sveta koji ce ti sigurno bolje od mene objasniti ali moram priznati da je i meni ovo smetalo u pocetku tj. i ja sam kontao da su to sve pointeri ali eto kao postoji neka razlika.

I na kraju moram priznati da su ti pitanja malo probudila forum. Eto srece da cesce neko postavi ovakva pitanja moglo bi se na kraju uciti sve sa foruma, bez kjniga :)

 
Odgovor na temu

Dragi Tata
Malo ispod Kanade

Član broj: 1958
Poruke: 3906
*.lionbridge.com.



+6 Profil

icon Re: .Net i C# dileme...18.04.2006. u 12:57 - pre 225 meseci
Citat:
_v!rus_:
1. Na osnovu postova ovde vidim da izgleda postoji jasna razlika između reference i pointera. Jel može neko to samo malo da pojasni?


Razlika jeste jasna i nije mi baš jasno otkud zabuna.

Reference: http://www.jaggersoft.com/csharp_standard/11.2.htm
Znači kad imaš recimo:

Code:

NekaKlasa r = new NekaKlasa();


r je referenca koja pokazuje na objekat u GC memoriji.

Sa druge strane, pointeri: http://www.jaggersoft.com/csharp_standard/25.2.htm
su manje više isti pointeri kao u C-u i mogu da se koriste samo u "unsafe" kontekstu. Iskreno, u C#u ih nikad nisam koristio niti znam ikog ko jeste.

Citat:
_v!rus_:
2. Ako sam dobro shvatio Dragog Tatu, rule of thumb bi bilo: object.Dispose() koristimo kada nam ne treba dalji rad sa objektom, actual memorija biti oslobođena tek kada GC stupi na scenu. Posle poziva object.Dispose() postaviti object = null da mi obavimo naš deo posla, a nek' framework brine o eventualnim svojim referencama. Jel to OK?


Jeste OK. A što se tiče postavljanja reference na null, to može da koristi ako ta referenca živi znatno duže nego objekat na kog pokazuje. Inače, samo je pustiš da izađe iz opsega.
 
Odgovor na temu

mmix
Miljan Mitrović
Chief Software Architect
Financial Intelligence Software Ltd.
Passau, Deutschland

SuperModerator
Član broj: 17944
Poruke: 6044



+4631 Profil

icon Re: .Net i C# dileme...18.04.2006. u 15:22 - pre 225 meseci
Citat:
_v!rus_
...e time sam mislio da se ruši "generičnost" jezika i frameworka čim hardkoduju kompajliranje za pojedine klase, mada mi ruku na srce zaista ne pada na pamet konkretan slučaj primene i kada bi bilo moguće napraviti svoj value tip. A i ta moja ideja je krenula od toga da su value types u stvari objekti, što se izgleda ispostavilo da je pogrešno. Na kraju krajeva, ništa bitno, samo 'nako, mislio sam da je neko najzad napravio generičan OO jezik, kada sam (pogrešno) pročitao da su simple types u stvari objekti.
@mmix
To da su svi simple(value) types u stvari objekti našao sam u Prof. C#, second edition (Wrox), pa sam shvatio zdravo za gotovo, tamo se ne pominju varijante sa "hard-coding"


Pazi komapjler to radi zato sto JIT/runtime to tako rade, to je do samog CLS-a. A sto se tice svog value type-a, veca primena bi bila u nasledjivanju postojeceg value tipa; npr hocu 32 bitni broj koji ima samo parne brojeve . U principu nevazno, neko sigurno ima i neki pametniji primer, ali svejedno ne moze jer ne postoji nacin da se to objasni CLS-u (sem custom wrapper klase, ali to nije isto (vidi dole)).

Ono sto ce tek da te mozda zbuni je cinjenica da CLS dozvoljava da se value type upakuje (boxing) u "svoj" genericki objekat. Taj objekat onda ide na HEAP i ima svoju kopiju vrednosti (ne predstavlja "pointer" na varijablu od koje je nastao:

Code:
int x = 3;
object xo = (object)x;
x = 5;
xo = 6;
x.ToString();


na kraju ovog koda x je lokalna varijabla na steku ciji je value-type Int32 i sa vrednoscu 5, dok ce xo biti referenca na objekat na HEAP-u ciji je type Int32 i sa internom vrednoscu 6.
Ono sto takodje moze da promakne ovde je da pomislis da xo i posle x0 = 6 drzi referencu na isti objekat koji je drzao vrednost 3 i da je samo promenio internu vrednost na 6, to medjutim nije tacno, CLS je zapravo kroz boxing kreirao novi objekat sa internom vrednoscu 6 i njegovu referencu ubacio u xo, dok je stara referenca otisla u zaborav i ceka da je GC zdrobi.

Dakle, value-type mogu biti objekti, ali ne po defaultu, moras da se "pomucis" za to Takodje imaj u vidu da ovde govorimo o implementaciji na PC-u na Windows-u. Niko tebe ne sprecava da napravis implementaciju CLSa koja uvek koristi objekte za value tipove

Citat:
_v!rus_:
Ovo mi nije baš najjasnije (distinction between metod klase i metod objekta, metod klase = static metod?, kako inace radi kada je ref. tip?), ako imas vremena plz pojasni, baš bi hteo da ukapiram kako se to ispod haube dešava....


Moj typo; oprosti, juce je bio mnogo plahovit dan U ovom primeru sam mislio sam na metod, iliti objektni metod, nikakve veze sa statickim (class) metodama.
Ako znas kako radi poziv metoda (razlika u odnosu na funkcije/class metode); onda znas da se pri svakom pozivu kao prvi implicitni parametar na stek prosledjuje referenca na objekat. Taj parametar je "nevidljiv" i u samoj metodi se referencira sa this (ili Me za VB.NET; ako se secam Delphi-a dobro, tamo je bilo "self"). E sad zamisli da na stek ne ide referenca na objekat nego zaista sama vrednost value-type-a (za npr. x gore ide 4 bajta koji predtsavljaju binarnu vrednost 5). Samim tim to nije referenca i this u ToString nije referenca nego vrednost 5 Samo sto je ToString za Int32 "nasviran" i zna sta mu je na steku i kako da ga obradi.
Ovo je sve moguce zato sto .NET stek nije ogranicen na 32bit chunks, ako tako pozeli CLI moze da stavi 1 bajt na stek, a moze i 8 ili 10 ili koliko mu vec treba da smesti neki value type.
Ti ovo ne mozes da primenjujes zato sto evaluacija implicitnog parametra u this ide automtski za sve metode koje ti mozes da napises.

E sad, pogledaj xo.ToString();
U ovom slucaju xo je object i na stek ne ide value-type nego referenca na instancu Int32 klase i poziv metoda ToString se obavlja preko vTable kao i za "tvoje" metode. Nekom magijom u jezgru CLSa metod Int32.ToString() zna kad je dobio value-type a kad referencu (moja pretpostavka je da cak CLS to resava interno sa dva razlicita metoda).

Citat:
_v!rus_:
Šta je u tom slučaju sa "originalnim" textBox1.Font? GC će ga zgazi jer je refCount=0?
I još par stvari, ako neko ima vremena, čisto rasprave radi:
1. Na osnovu postova ovde vidim da izgleda postoji jasna razlika između reference i pointera. Jel može neko to samo malo da pojasni?
2. Ako sam dobro shvatio Dragog Tatu, rule of thumb bi bilo: object.Dispose() koristimo kada nam ne treba dalji rad sa objektom, actual memorija biti oslobođena tek kada GC stupi na scenu. Posle poziva object.Dispose() postaviti object = null da mi obavimo naš deo posla, a nek' framework brine o eventualnim svojim referencama. Jel to OK?


Ok, prva stvar, .NET nije COM2.0 .NET objekti ne koriste reference counting. Cak ni kad je .NET objekat publikovan kao COM objekat (u tom slucaju CCW pravi COM proxy u kome drzi reference counter). GC radi na sasvim drugaciji nacin. Vise detalja u ova dva clanka:

Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework
Garbage Collection—Part 2: Automatic Memory Management in the Microsoft .NET Framework
Ovde ima sve detaljno objasnjeno plus neke zanimljivosti o geenracijama i jedinstvenoj mogucnosti .NET objekata (mogucnosti da vaskrsnu )

Ali ukratko:

1. Referenca pokazuje na objekat . Kako to radi nije konkretno stvar C#-a nego implementacije CLS-a Znam da je to zbunjujuce, ali postoji ta zona sivila izmedju samog standarda i njegove implementacije, posto je standard cross-platform, a implementacija platform dependant.

Na PC-u pod windows-om referenca je (uprosceno) pointer na pointer na memorijski blok na HEAP-u ako je lokalna varijabla, ili pointer na objekat ako je polje u drugom objektu

npr: Font x = new Font();

x je lokalna varijabla (referenca) i u stvari je pointer u ROOTS segment aplikacije (koji je negde tamo ). Taj pointer se nece promeniti dok god je varijabla x u scope-u. Lokacija u ROOTS-u na koju pointer u x-u pokazuje je u stvari pointer na HEAP gde se nalazi memorijski footprint instance klase Font.
Kad GC obavi cleanup, pomerice instancu na HEAP-u i promenice njenu adresu na odgovarajucoj lokaciji u ROOTS-u; samim tim referenca x i dalje pokazuje (preko dva koraka) na isti objekat iako je njegova fizicka lokacija u memoriji promenjena. A da ti ne bi lupao glavu oko toga sta je gde pomereno i kako, C# ti omogucava da koristis x = 3; umesto **x = 3;
Ovime je takodje omoguceno da GC ne mora da juri sve moguce pointere na HEAP po aplikaciji posto su svi lepo hijerarhijski poredjani u ROOTS-u

Posto svi "zivi objekti" moraju da postoje u ROOTS-u ili da budu polja u objektima koji su u ROOTS-u, GC moze da rekurzivno napravi memorijsku mapu zivih objekata (nasuprot svim objektima) i da tako bez reference counter-a odredi koji objekti su "mrtvi" i mogu da se izbace iz memorije. Vise detalja imas u gornja dva clanka.

2. Dispose nije deo .NET tehnologije, Dispose je pattern koji je veoma lepo primenljiv na ono sto je DragiTata napomenuo, potrebu da se oslobode unmanaged resursi (Implementing Finalize and Dispose to Clean Up Unmanaged Resources) Posto se GC nece pokretati bez preke potrebe (na serverima sa dosta memorije to moze da bude tek kad se aplikacija ugasi sto moze da bude i par meseci nakon sto su sve reference nullovane i sve to vreme ce unamanged resurs biti zakljucan), Dispose se koristi da bi se ti resursi oslobodili bez potrebe da se ceka na GC. Sam .NET Framework koristi Dispose pattern u klasama koje barataju sa unmanaged resursima.

Jedina stvar koja mene neopisivo nervira u ovom paternu je to "ziv sam al sam mrtav" stanje u kome je objekat nakon poziva Dispose()

Chris je razjasnio neke zablude o Dispose-u u http://blogs.msdn.com/clyon/archive/2004/09/21/232445.aspx

Tako da je odgovor na tvoje pitanje DA, posle dispose postavi sve reference na null jer je objekat ionako neupotrebljiv bez tih unmanged resursa koje si upravo oslobodio, a kad GC odradi svoj posao bas te pa briga


E sad, samo jos jedna stvar, cisto da smo nacisto zasto je CLS na PC/Windows nasviran da favorizuje value-types. Problem je sa cisto sa stanovista performansi. Pogledajmo memory footprint za x i xo iz gornjih primera:

x zauzima 4 bajta na steku
xo zauzima: 4 bajta na steku za prvi pointer, 4 bajta u ROOTs-u za HEAP pointer; na HEAP-u: 4 bajta za vTable, 4 bajta za SyncLock polje i 4 bajta za sam integer value , dakle 12 bajtova za isntancu Int23 kalse plus 8 overhead, ukupno 20 bajtova.

Array od milion integera ce dakle zauzimati 4.000.012 bajtova (tih 12 bajtova posto je array i sam objekat), dok ce array od milion integer objekata zauzimati 12.000.012 bajtova. Pristupanje svakom elementu prvog niza je pristup vrednosti, pristup svakom elementu drugog niza je reference evaluation da bi se doslo do interne promenljive koja drzi vrednost. Da nema nasviranosti .NET bi bio spor koliko i VB6 ako ne i sporiji
Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog
naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji
je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan,
sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv - Z.Đinđić
 
Odgovor na temu

mmix
Miljan Mitrović
Chief Software Architect
Financial Intelligence Software Ltd.
Passau, Deutschland

SuperModerator
Član broj: 17944
Poruke: 6044



+4631 Profil

icon Re: .Net i C# dileme...18.04.2006. u 15:49 - pre 225 meseci
Citat:
mmix:
Ako znas kako radi poziv metoda (razlika u odnosu na funkcije/class metode); onda znas da se pri svakom pozivu kao prvi implicitni parametar na stek prosledjuje referenca na objekat.


Da me neko pogresno ne razume ovde, kad kazem "baca na stek" pri pozivu metoda, razmisljam o klasicnom "skolskom" pozivanju metoda. JIT kompajler radi optimizaciju kad god moze, i ako moze da zaobidje stek i parametar prosledi preko registra, on ce to i uraditi. Dakle, "baca na stek" uzmi sa rezervom

PS Upravo sam proverio kroz dissambler, i moja sumnja je bila opravdana,

x.ToString() i xo.ToString() pozivaju dve razlicite "funkcije" u mscorelib.dll.
xo.ToString() interno poziva x.ToString() verziju funcije (naravno gde je x interna vrednost xo objekta), ali to je mehanizam po kome diferencira value-type i reference-type za osnovne tipove.

[Ovu poruku je menjao mmix dana 18.04.2006. u 16:55 GMT+1]
Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog
naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji
je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan,
sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv - Z.Đinđić
 
Odgovor na temu

_v!rus_
BGD

Član broj: 40451
Poruke: 313
*.dsl.siol.net.



+1 Profil

icon Re: .Net i C# dileme...18.04.2006. u 19:03 - pre 224 meseci
Šta da kažem, hvala na iscrpnim objašnjenjima i linkovima.

Ne mogu baš da kažem da mi je sve "iz prve" jasno, ali svakako da treba par puta preci. U principu, najviše me je zanimao taj osnovni deo, najlakše je posle samo nabubati (ipak prilicno obiman) framework. Napravio sam veeeliku grešku pre par godina kada sam pocinjao sa Delphi-jem što nisam taj memory managment savladao u startu, kasnije me koštalo mnogo sati debagovanja stvari koje "naizgled" rade ok N puta i na N+1 padnu, tako da stvarno imam, kako mmix kaže, "povišen nivo opreznosti".

Moram da pomenem da mi se posebno svideo onaj genijalni sistem sa referenciranjem memorije na 2 nivoa, iako je možda to "topla voda" koja postoji i davno pre .net-a. Nisam shvatio prednost iz prve, tek se kasnije upalila lampica...
 
Odgovor na temu

mmix
Miljan Mitrović
Chief Software Architect
Financial Intelligence Software Ltd.
Passau, Deutschland

SuperModerator
Član broj: 17944
Poruke: 6044



+4631 Profil

icon Re: .Net i C# dileme...18.04.2006. u 20:27 - pre 224 meseci
Ako te bas interesuje kako sve to konkretno radi, skini ovaj fajl:
Shared Source Common Language Infrastructure 2.0 Release

(trebace ti neki arhiver koji moze da raspakuje tgz i tar; noviji WinZip to moze)

imas u fajlovima
/sscli20/clr/src/bcl/system/gc.cs - .net klasa
/sscli20/clr/src/vm/gc*.* - native implementacija GCa

ovo je naravno prilicno komplikovano, i veci deo logike je u gcimpl.cpp fajlu koji je C++ koliko se to moze biti , ali to je definitivno implementacija koja trenutno vazi za .NET 2.0. Ja ovu arhivu pogledam sa vremena na vreme kad sam dokon i kad me bas interesuje kako nesto radi veoma low-level. GC nije jedina stvar ovde, ceo JIT je tu, remoting (sa sve sorsom za fabricke kanale) i jos neke CLI stvarcice. Naravno, nema sors za sam .NET Framework.

Kao sto kazu u readfirst.html, Have fun




Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog
naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji
je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan,
sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv - Z.Đinđić
 
Odgovor na temu

[es] :: .NET :: .NET Desktop razvoj :: .Net i C# dileme...

[ Pregleda: 4142 | Odgovora: 15 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.