210 likes | 320 Views
Microsoft.NET környezet. Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz. 1. Referencia vs érték típus. A pointer a memória egy címét tartalmazza. Ezen a memóricen egy ‘nagy’ méretű adathalmaz található
E N D
Microsoft.NET környezet Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz 1
Referencia vs érték típus A pointer a memória egy címét tartalmazza. Ezen a memóricen egy ‘nagy’ méretű adathalmaz található (pl string, tömb, objektum sok mezővel, …). TKor k; ... null k = new TKor(); ... cím TKor példány mezők 2
Referencia vs érték típus Két pointer alapú változó közötti értékadás során csak a memóriacím másolódik át! TKor k = new TKor(); TKor p = k; ... cím cím TKor példány mezők 3
Referencia vs érték típus TKor k = new TKor(); k.sugar = 10; TKor p = k; p.sugar = 20; Console.WriteLine( k.sugar ); void Beallit( Tkor x ) { x.sugar = 25; } TKor k = new TKor(); k.sugar = 10; Beallit( k ); Console.WriteLine( k.sugar ); 4
Referencia vs érték típus Minden osztály típusú változó mindig pointer típusú is egyben! A pointer-t a .NET környezetben referencia-nak nevezik. A referencia változó lényegében pointer változó. A referenciák által mutatott terület típusos, és a GC felügyeli ezeket a területeket. Van ilyen fogalom is a .NET-ben, hogy pointer, de az a hagyományos pointert jelenti (C, C++ fogalom), amely nem típusos, és az általuk mutatott területeket a GC nem felügyeli ( a programozónak kell felszabadítani explicit módon).
Referencia vs érték típus Minden példány változó 4 byte helyet foglal el. Alapértelmezett értéke a ‘null’, vagyis hogy nincs még hozzá tartozó tényleges példány-terület. Két ilyen példány-változó közötti értékadás során csak a címek másolódnak át (gyors). Fv-ek felé történő paraméterátadás során ez mindig cím szerinti paraméterátadást jelent! TKor k = new TKor(); ... k = null; Már jöhet is a GC, és takaríthatja ki a lefoglalt TKor példányt…
Referencia vs érték típus int a = 10; int b = a; b = 12; Console.WriteLine( a ); Nem lenne jó, ha itt a 12 íródna ki! Az alap típusok (int, bool, char, double, … ) változók nem referencia elvűek. Ezeket value-type (érték- típusoknak nevezzük). int a = 10; ... 10 10 int b = a; b = 12; 7
Referencia vs érték típus Az érték-típusú változókhoz tartozó memóriaterületen maga az érték tárolódik. A közöttük történő értékadás során az érték másolódik át egyik cellából a másikba. Az ilyen típusú fv-paraméterek alapból érték szerinti paraméterátadással működnek: void Beallit( int x ) { x = 25; } int a = 10; Beallit( a ); Console.WriteLine( a ); // még mindig 10
Referencia vs érték típus Az érték-típusú változók cím szerinti paraméterátadását a ‘ref’ kulcsszóval kell megjelölni: void Beallit( ref int x ) { x = 25; } int a = 10; Beallit( ref a ); Console.WriteLine( a ); // most 25
Referencia vs érték típus Érték-típusú osztályt tudunk csinálni, de akkor nem a ‘class’, hanem a ‘struct’ szót kell használni: struct Teglalap { public int x; public int y; public int szeles; public int magas; } Teglalap keret = new Teglalap(); ... x=0, y=0, ... 10
Referencia vs érték típus • Ha C#-ban a struct-al definiálunk egy példányt: • Nem kell a new kulcsszót használni a példányosí- táshoz • Ha nem használjuk a new kulcsszót, akkor a struktúra mezőinek nem lesz kezdőértéke (memóriaszemét) • Ilyen osztály mezőire nem használhatunk kezdőértékadást. • Ezért a struct-nak általában van konstruktora • A paraméter nélküli (default) konstruktort a nyelv automatikusan készíti. Mi csak paraméteres konstruktort készíthetünk!
Referencia vs érték típus A struct típus korlátozott OOP tulajdonságokkal rendelkezik, pl. nem működik rá az öröklődés semmilyen formában (egy struct nem lehet ős, ő nem lehet gyermek) Ugyanakkor a struct őse is az Object Viszont implementálhat interface-t A példányosítás kevesebb memóriát igényel, mert a példány nem kerül +4 byte-ba a referencia tárolása miatt.
Referencia vs érték típus Amíg a struktúra mezői nincsenek feltöltve, addig nem használható fel (undefined). int a; int b = a+1; int a = 0; int b = a+1; int a = new int(); int b = a+1; Az ‘int’ név valójában alias neve a System.Int32-nek! namespace System { struct Int32 { ... } } using System; Int32 a = new Int32();
Referencia vs érték típus int[] ertekek = new int[20]; ... foreach(int a in ertekek) { a = 0; // hibás !!! } A fenti kód azért hibás, mert a tömbben lévő értékeket a foreach ciklus sorban átmásolja az ‘a’ változóba. De az ‘a’ változóba történő értékadás nem másolódna vissza automatikusan a vektor megfelelő elemébe, ezért értelmetlen…
Referencia vs érték típus ArrayList tanulok = new ArrayList(); ... foreach(Tanulo t in tanulok) { t.neve = ”Pista”; } A fenti kód azért nem hibás, mert nem a ‘t’ változó értékét módosítjuk, hanem az általa mutatott memória-területen végzünk módosításokat. Azt szabad…
Referencia vs érték típus A String típus nem value-type, hanem reference-type… string s = ”Hello”; string x = s; x s ... cím cím ”Hello”
Referencia vs érték típus A String típus nem value-type, hanem reference-type… string s = ”Hello”; string x = s+” akarki”; string u = s.ToUpper(); x s u ”HELLO” cím cím cím ”Hello” ”Hello akarki”
Referencia vs érték típus A String összefüzés nem túl hatékony: string s = ”a=”+a.ToString()+” Ft”; • valahol „a=„ • elkészül a „a=12” • elkészül a „a=12 Ft” A közben keletkezetett rész-eredményeket a GC majd el fogja takarítani… idővel… s = s.Trim().ToUpper(); Első körben s-ről levágja a bevezető és záró white space-kat (eredeti s-t a GC eltakarítja), majd nagybetűre alakítja (előző változatot GC eltakarítja)
Referencia vs érték típus Ha egy string típusú értékhez folyamatosan hozzá- fűzünk, akkor célszerűbb a System.Text.StringBuilder egy példányát használni! String ki = ”a=”+a.ToString()+” Ft”; StringBuilder s = new StringBuilder(); s.Append( ”a=” ); s.Append( a.ToString() ); s.Append( ”Ft” ); string ki = s.ToString(); vagy… string ki = String.Format(”a={0} Ft”,a);
Referencia vs érték típus void Atallit(string s) { s = s+” es Juliska”; } string mese = ”Jancsi”; Atallit( mese ); Console.WriteLine( mese ); Mi fog kiíródni a képernyőre? mese s ”Jancsi” cím cím ”Jancsi és Juliska”
Referencia vs érték típus void Atallit(ref string s) { s = s+” es Juliska”; } string mese = ”Jancsi”; Atallit( ref mese ); Console.WriteLine( mese ); Mi fog kiíródni a képernyőre? mese s ”Jancsi” cím ”Jancsi és Juliska”