Az előadás letöltése folymat van. Kérjük, várjon

Az előadás letöltése folymat van. Kérjük, várjon

Framework fundamentumok

Hasonló előadás


Az előadások a következő témára: "Framework fundamentumok"— Előadás másolata:

1 Framework fundamentumok
Turóczy Attila (MCT, MCP, MCTS) Livesoft Kft

2 A C# evolúciója C# 3.0 C# 2.0 C# 1.0 Nyelvbe ágyazott lekérdezések
.NET CLR C# 2002 1.0 2003 1.1 2005 2.0 2006 3.0 2007 3.5 C# 3.0 Nyelvbe ágyazott lekérdezések C# 2.0 Típusbiztosabb, hatékonyabb nyelv Generikus típusok, yield return A C# 1.0 megjelentek a propertyk A C# 2.0 Generikus típusokkal hatékonyságot növeljük. Hisz kevesebb memóriát eszik az alkalmazásunk, a fordítás idejű hibákat kiszűrjük. Nincs Boxing se unboxing, így memória barát is. A C# 3.0 előzetes specifikációja már 2005-ben megjelent. Delphi és C# Anders Hejlsberg C# 1.0 Komponensek felügyelt környezetben Property, delegate, event

3 Érték típusok Nyelvi elemek Programozói típusok Referencia típusok
Tematika Érték típusok Nyelvi elemek Programozói típusok Referencia típusok Osztályok Típus konverzió C# 3.0 Egy rövid áttekintőt fog adni az alábbi fejezetekről. Úgy mint a saját típusok készítése, típus konverziók stb.

4 A .NET keretrendszer legegyszerűbb típusai.
Érték típusok A .NET keretrendszer legegyszerűbb típusai. Érték típusú változók közvetlenül a hozzájuk rendelt értéket tartalmazzák. Érték típusú változók tárolása a stack-ben történik. Mindegyik érték típus a System.ValueType alap típusból származik. Az objektumok tárolás pedig a heapben.

5 Érték típusok Az érték típusok három csoportba oszthatók.
Beépített típusok Programozói típusok Felsorolások Az érték típusok három csoportba oszthatók. Beépített típusok (Built-in types): azok a típusok, amelyek a .NET keretrendszer, mint érték szerint kezelendő típus definiál (pl. int, DateTime stb.) Programozói típusok (User-definied types): azok a típusok, amelyeket a programban definiál a programozó a struct kulcsszóval. Tehát struktúrák. Felsorolások (Enumerations): a .NET keretrendszerben vagy a programozó által enum kulcsszóval definiált típusok

6 Beépített numerikus típusok
Név (C# alias) Méret Tartomány System.SByte (sbyte) 1 byte -128 – 127 System.Byte (byte) 0 – 255 System.Int16 (short) 2 byte – 32767 System.Int32 (int) 4 byte System.UInt32 (uint) 0 – System.Int64 (long) 8 byte -9, * 1018 – 9, * 1018 System.Single (float) -3, * 1038 – 3, * 1038 System.Double (double) -1, * – 1, * 10308 System.Decimal (decimal) 16 byte -7, * , * 1028 A beépített értéktípusok gyakran használatosak a C# programokban, ezért a nyelv saját elnevezéseket (alias) definiál a könnyebb használhatóság érdekében. Célszerű mindig a 32 bites integereket használni (Int32, UInt32) ,mert a runtime erre van optimalizálva. A Float és Double használata a legköltségesebb mert azt a hardware optimalizálja.

7 Beépített egyéb típusok
Név (C# alias) Méret Tartomány System.Char (char) 2 byte - System.Boolean (bool) 4 byte System.IntPtr Platform függő System.DateTime (date) 8 byte :00:00 :59:59 Még kb. 300 beépített érték típus található a .NET keretrendszerben A karakterek tárolásához használt kódlap az unicode (ezért foglal 2 byte-ot egy karakter). Bár az érték típusok gyakran csak egyszerű értékeket reprezentálnak, ezek is objektumként funkcionálnak (pl. meghívhatók a műveleteik). Ugyanis a .NET Frameworkben minden típus a System.Object osztályból származik. Ha ezek mind érték típusok akkor, hogy hogy van ToString, Equals, GetType stb metódusok?

8 Érték típus deklarálása
Ahhoz, hogy ezeket a típusokat használjuk, deklarálnunk kell őket. Az értéktípusoknak implicit konstruktoruk van. (Nem kell használni a new kulcsszót) A konstruktor alapértelmezett 0 vagy null értéket ad. int i = 12; bool b = false; A Nullázható változók a .NET 2.0 -ban jelentek meg. Elnevezési konvenciók: Csak (kis- és nagybetűs) betűk, számok és aláhúzás-karakterek lehetnek a nevében. A névnek betűvel kell kezdődnie (aláhúzás karakter annak számít) A C# case-sensitive nyelv!

9 Olyan érték típusú változók, amelyek null értéket is felvehetnek.
Nullázható változók Olyan érték típusú változók, amelyek null értéket is felvehetnek. A null értékkel azt jelölhetjük, ha a változó még nem kapott értéket. A nullable típusoknak HasValue és Value tulajdonságaik lesznek. A HasValue megállapítja, hogy a változónak van-e értéke. A Nullázható változók a .NET 2.0 -ban jelentek meg. Nullable<bool> b = null; bool? b = null; //Lehetséges értékek: true, false vagy null A Nullable típus a .NET Framework 2.0 –ban jelent meg.

10 demo Nullázható változók DEMO Console Application bool? b = null;
if (b.HasValue) { Console.WriteLine("A b értéke:" + b.Value); } else Console.WriteLine("A b nincs beállitva");

11 Érték típusok Nyelvi elemek Programozói típusok Referencia típusok
Tematika Érték típusok Nyelvi elemek Programozói típusok Referencia típusok Osztályok Típus konverzió C# 3.0

12 Felsorolások - Enumeráció
Rögzített értékek halmazából készített típus Az enum nyelvi kulcsszóval definiálhatunk felsorolásokat Tulajdonképpen csak egy szám, aminek egyes értékeihez nevet rendelünk A kód olvashatóságát segíti elő Leginkább akkor használatosak, ha egy változó értéktartományát korlátozni szeretnénk enum Szín { Piros, Zöld, Kék }; Szín s = Szín.Piros; Console.WriteLine("{0}", s);

13 Az elágazás elejét jelzi Mindenképpen követnie kell egy feltételnek
Elágazások - if Az if kulcsszó Az elágazás elejét jelzi Mindenképpen követnie kell egy feltételnek Az else kulcsszó Nem kötelező, az elágazás utolsó eleme Nincs mögötte feltétel Több feltétel is lehet && és || operátorok int i = 2; string s = "Hello"; if (i > 2) { … } else if ((i == 2) && s == ””) else { … }

14 A vizsgált változó követi A case kulcsszó A default kulcsszó
Elágazások - switch A switch kulcsszó A vizsgált változó követi A case kulcsszó A default kulcsszó Nem kötelező A break kulcsszó Kilép a switchből enum Suit { Clubs, Hearts, Diamonds, Spades } Suit trumps = Suit.Hearts; switch (trumps) { case Suit.Clubs : case Suit.Spades : color = "Black"; break; case Suit.Hearts : case Suit.Diamonds : color = "Red"; break; default: color = "ERROR"; break; }

15 A while kulcsszó vezeti be
Iterációk: while A while kulcsszó vezeti be A kulcsszót követő blokk tartalmazza a feltételt A blokk futtatása előtt vizsgálja a feltételt int i = 0; while (i < 10) { Console.WriteLine(i); i++; } // 0-tól 9ig írja ki a számokat int i = 0; while (i < 10) { Console.WriteLine(i); i++; } // 0-tól 9ig írja ki a számokat

16 A while kulcsszó vezeti be
Iterációk: do while A do kulcsszó vezeti be A while kulcsszó vezeti be A kulcsszót követő blokk tartalmazza a feltételt A blokk futtatása előtt vizsgálja a feltételt int i = 0; do { Console.WriteLine(i); i++; } while (i < 10) // 0-tól 9ig írja ki a számokat int i = 0; do { Console.WriteLine(i); i++; } while (i < 10) // 0-tól 9ig írja ki a számokat

17 A for kulcsszó vezeti be
Iterációk: for A for kulcsszó vezeti be A kulcsszót követő blokk tartalmazza a feltételt és a ciklusváltozót A ciklusváltozó csak az if blokkján belül érvényes A blokk futtatása előtt vizsgálja a feltételt Több ciklusváltozó is megengedett for (int i = 0; i < 10; i++) { Console.WriteLine(i); } Console.WriteLine(i); //Hiba! for (int i = 0; i < 10; i++) { Console.WriteLine(i); } Console.WriteLine(i); //Hiba! for (int i = 0, j = 0; ... ; i++, j++) { … } for (int i = 0, j = 0; ... ; i++, j++) { … }

18 A foreach kulcsszó vezeti be Gyűjtemények végigfuttatására!
Iterációk: foreach A foreach kulcsszó vezeti be Gyűjtemények végigfuttatására! Előre megválasztható a ciklusváltozó típusa és neve Int32[] numbers = new Int32[10]; for (int i = 0; i < 10; i++) { numbers[i]; } foreach (int number in numbers) Console.WriteLine(number); Int32[] numbers = new Int32[10]; for (int i = 0; i < 10; i++) { numbers[i]; } foreach (int number in numbers) Console.WriteLine(number);

19 Érték típusok Nyelvi elemek Programozói típusok Referencia típusok
Tematika Érték típusok Nyelvi elemek Programozói típusok Referencia típusok Osztályok Típus konverzió C# 3.0 Egy rövid áttekintőt fog adni az alábbi fejezetekről. Úgy mint a saját típusok készítése, típus konverziók stb.

20 Programozói (érték) típus
Más néven struktúra (a struct nyelvi kulcsszó segítségével definiálható) „Egyszerű” típusok kompozíciója, a könnyebb kezelés érdekében Nagyon hasonlóak az osztályokhoz. Definiálhatunk bennük Adattagokat |Tulajdonságokat |Műveleteket | Eseményeket |Beágyazott típusokat Másoláskor az adat másolódik! Mikor érdemes használni? Kis típusok esetén érdemes használni. Vagy, ha logikailag összetartozó változókat fog össze (attribútumok). Ha a létrehozás után nem változtatjuk és ha nincs szükség referencia típusra való konverzióra És a mérete kisebb mint 16 Thread stack, a szállal együtt semmisül meg • Deklarációkor automatikusan hívódik a default konstruktor – Ezt nem is lehet felüldefiniálni

21 Struktúrák példa struct Cycle {
private int _val, _min, _max; // Adattag public Cycle(int min_in, int max_in) // Konstruktor ... } public int Value // Tulajdonságok get { return _val; } set { _val = value; } public override string ToString() // Művelet

22 Érték típusok Nyelvi elemek Programozói típusok Referencia típusok
Tematika Érték típusok Nyelvi elemek Programozói típusok Referencia típusok Osztályok Típus konverzió C# 3.0 Egy rövid áttekintőt fog adni az alábbi fejezetekről. Úgy mint a saját típusok készítése, típus konverziók stb.

23 A .NET keretrendszer típusainak nagy része ilyen.
Referencia típusok A .NET keretrendszer típusainak nagy része ilyen. A referencia típusú változók a hozzájuk rendelt érték memóriacímét tartalmazzák. A referencia típusú változók a korábbi programozási nyelvek mutatóinak (pointer) feleltethetők meg. Heapben találhatók Megszüntetésükről a GC gondoskodik. A GC akkor lép müködésbe amikor a rendszer már jónak látják, de meghívjuk a GC.Collectet.

24 A .NET keretrendszerben kb. 2500 különféle referencia típus található.
Referencia típusok Név Mire jó? System.Object A legáltalánosabb típus (minden típus közös őse) System.String Szövegek System.Text.StringBuilder Dinamikus szövegek System.Array Adatok tömbje (minden tömbtípus közös őse) System.IO.Stream I/O puffer System.Exception Általános kivétel (minden kivételtípus közös őse) A .NET keretrendszerben kb különféle referencia típus található. Ezek a leggyakrabban használt referencia típusok.

25 Stringek és a String Builder
Csak az utolsó String lesz referenciája! A többi a GC kisöpri. Ezen teljesítményprobléma elkerülésére használjuk a StrinBuilder osztályt string s; s = "wombat"; s += " Kangoroo"; s += " wallaby"; s += " koala"; Console.WriteLine(s); System.Text.StringBuilder sb = new StringBuilder(30); sb.Append("wombat"); sb.Append(" kangoroo"); sb.Append(" wallaby"); sb.Append(" koala"); string s = sb.ToString(); Console.WriteLine(s);

26 Tömböket egyszerűen kezelhetünk, sorba rendezhetünk.
Tömbök és kezelésük Tömböket egyszerűen kezelhetünk, sorba rendezhetünk. (Sokszor célszerű generikus listákat alkalmazni, mint egyszerű tömböket. Erről később) int[] ar = { 3, 1, 2 }; Array.Sort(ar); Console.WriteLine("{0}, {1}, {2}", ar[0], ar[1], ar[2]);

27 Kivételkezelés: try, catch
A try kulcsszó nyitja a logika blokkját A catch kulcsszó nyitja a hibakezelő blokkot – A kulcsszó után adhatjuk meg a kezelendő kivétel típusát és nevét try { StreamReader stReader = new Console.WriteLine(stReader.ReadToEnd()); } catch (Exception ex) Console.WriteLine("Error: " + ex.Message); try { Console.Write("Enter a number: "); int i = int.Parse(Console.ReadLine()); } catch (OverflowException oex) { Console.WriteLine(oex);

28 Kivételkezelés: catch, catch
Több catch blokkunk is lehet – Minden blokk egy típust és az abból származókat kapja csak el – A kiértékelés felülről-lefelé halad, az első nyer A legspecifikusabbtól a legáltalánosabbig haladjunk try { StreamReader stReader = new Console.WriteLine(stReader.ReadToEnd()); } catch (FileNotFoundException) Console.WriteLine("The file could not be found"); catch (UnauthorizedAccessException) { Console.WriteLine("Access Denied"); } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); } try { /* kivételeket kiváltó kód */ } catch (ArgumentNullException anex) { /**/ } catch (ArgumentException aex) catch (Exception) { /*névtelen blokk*/ }

29 Kivételkezelés: finally A finally kulcsszó nyitja a cleanup blokkot
A finally blokk mindenképpen lefut Csak egy lehet belőle, a catchek után Ha van finally, nem kötelező a catch Jellemzően a fájlok lezárását stb. tesszük ide StreamReader stReader = new try { Console.WriteLine(stReader.ReadToEnd()); } catch (Exception ex) Console.WriteLine("Error: " + ex.Message); finally stReader.Close();

30 Programozói – referencia típusok
Osztály (a class nyelvi kulcsszó segítségével definiálható) Interfész (az interface nyelvi kulcsszó segítségével definiálható) Delegált (a delegate nyelvi kulcsszó segítségével definiálható) Esemény (az event nyelvi kulcsszó segítségével definiálható) A referencia típusú változók adatainak tárolása a heap-ben történik, maga a referencia (memóriacím) a stack-ben keletkezik. A hivatkozott memóriaterület (objektum adatai) felszabadítása akkor történik, ha már nincs olyan referencia a programban, amely erre a területre hivatkozik.

31 demo Value Type Vs Reference Type class Program {
static void Main(string[] args) Numbers n1 = new Numbers(); n1.MyNumb = 3; Numbers n2 = n1; n2.MyNumb = 1000; Console.WriteLine("N1:"+n1.MyNumb + " N2:"+ n2.MyNumb ); Console.ReadLine(); } struct Numbers private int myNumb; public int MyNumb get { return myNumb; } set { myNumb = value; }

32 Típusok összehasonlítása

33 Érték típusok Nyelvi elemek Programozói típusok Referencia típusok
Tematika Érték típusok Nyelvi elemek Programozói típusok Referencia típusok Osztályok Típus konverzió C# 3.0 Egy rövid áttekintőt fog adni az alábbi fejezetekről. Úgy mint a saját típusok készítése, típus konverziók stb.

34 Osztályok A class kulcsszó vezeti be
Azonos szerkezetű objektumok halmaza (osztálydefiníció = a szerkezet leírása) Öröklés Minden osztály a System.Object leszármazottja Minden osztálynak csak egy őse lehet… Polimorfizmus Őstípusként deklarált objektum értékül kaphat utódtípusút, fordítva nem! Elemei: Adattagok |Tulajdonságok |Műveletek |Események | Beágyazott típusok

35 Több szóból álló neveknél: PascalCasing
Elnevezési konvenciók A típusnevek nagybetűvel kezdődnek String, Int32, Byte, CultureAndRegionInfoBuilder A változók nevének első betűje kicsi MyClass myClass = new MyClass(); Az interfészek neve elé I betűt teszünk IDisposable, Ienumerable, stb Több szóból álló neveknél: PascalCasing Egy név ne kezdődjön számmal, aláhúzással Ne álljon csupa nagybetűből egy név Programunk névterének neve ne egyezzen meg egy referált névterével se … de úgyis a cég dönt az elnevezésekről. Az objektumok tárolás pedig a heapben.

36 Egy értéket tartalmazó memóriaterület
Adattagok (Field) Egy értéket tartalmazó memóriaterület Az osztálydefiníció azon elemei, amelyek az osztály objektumai által tárolandó adatok szerkezetét (típusait) írják le Definíció: <láthatóság> <típus> <név>; Az osztály elemeinek definiálásakor meg kell adni a láthatósági kategóriát, amely szabályozza, hogy az egyes elemekhez a kód mely részéből férhetünk hozzá. private = csak az osztály kódjából érhető el protected = az osztály és a belőle származott osztályok kódjából érhető el public = minden olyan kódból elérhető, ahonnan az osztály is internal = csak abból az assembly-ből érhető el, amely az osztályt definiálja protected internal = a protected és az internal jelentésének kombinációja private int n;

37 public: bárki, bárhol bármit láthat
Láthatóság public: bárki, bárhol bármit láthat private: csak az osztály/objektum maga éri el protected: csak az osztály/objektum, illetve leszármazottai érik el internal: csak az osztály és a vele egy assemblyben lévő osztályok érik el protected internal: csak az osztály, annak leszármazottai és/vagy az osztállyal egy assemblyben lévő objektumok érik el Az osztály elemeinek definiálásakor meg kell adni a láthatósági kategóriát, amely szabályozza, hogy az egyes elemekhez a kód mely részéből férhetünk hozzá. private = csak az osztály kódjából érhető el protected = az osztály és a belőle származott osztályok kódjából érhető el public = minden olyan kódból elérhető, ahonnan az osztály is internal = csak abból az assembly-ből érhető el, amely az osztályt definiálja protected internal = a protected és az internal jelentésének kombinációja

38 Változók hatóköre Egy adattag abban a blokkban látható, ahol deklarálták Egy blokk nem deklarálhat olyan változót, melynek neve megegyezik az őt tartalmazó blokk egy változójának nevével Két egy szinten lévő blokk deklarálhat azonos nevű változót

39 Tulajdonságok (Property)
Az adatok egységbezárását támogató elemek Átmenet az attribútum és a művelet között Egy mezőt szabályozottan írhatóvá és/vagy olvashatóvá tévő metóduspár Definíció: <láthatóság> <típus> <név> { [<get művelet>] [<set művelet>] } A tulajdonságok segítségével – akár bonyolult – ellenőrzéseket is elvégezhetünk az adathoz való hozzáférések előtt. Így az adatok a módosítások után is megfelelnek a szükséges invariáns feltételeknek. public string Név { get { return this.név; } set { this.név = value; } }

40 Konstruktorok Az objektumok létrehozásában, az attribútumok kezdeti értékeinek beállításában játszanak fontos szerepet Speciális műveletek A konstruktor neve azonos az osztály nevével! Olyan művelet, amelynek nincs típusa A konstruktorok hívása a new operátor használatával egyidőben történik. A new operátor lefoglalja az adatok tárolásához szükséges memóriaterületet, a konstruktor feltölti ezt a területet az alapértelmezett értékekkel.

41 Osztályok (Példa) class Kör { private double sugár;
public double Sugár get { return sugár; } set { if(value > 0) sugár = value; } public Kör(double sugár_in) sugár = sugár_in; public double Kerület() return 2 * 3.14 * sugár;

42 A partial nyelvi kulcsszóval jelölhetjük
Parciális osztályok Olyan osztályok melyek esetében az osztály teljes definíciója több forrásfájlban szétosztva található A partial nyelvi kulcsszóval jelölhetjük Ez a szétválasztás általában a kód olvashatóságát segíti elő A parciális osztályok a .NET keretrendszer 2.0-ban jelentek meg.

43 demo Parciális osztály DEMO Console Application partial class Person {
public int Age { get; set; } public string Name { get; set; } } //Person.Manger partial class Person public string Job { get; set; } Person p = new Person(); p.Job = „Nagyon komoly manager"; Console.WriteLine(p.Job);

44 Absztrakt osztályok Olyan osztály, melynek legalább egy absztrakt (megvalósítás nélküli) művelete van abstract class Sokszög { private int csúcsok; public abstract double Kerület(); public abstract double Terület(); } Az absztrakt műveletek az osztály leszármazottjaiban kerülnek megvalósításra (vagy a származtatott osztály is absztrakt lesz).

45 [attribute(positional_params,named_param=value, ...)] element
Attribútumok Deklaratív címkék Az adott tag viselkedését (is) szabályozhatják A metaadatokkal együtt kerülnek tárolásra Reflexió segítségével felhasználhatjuk őket [attribute(positional_params,named_param=value, ...)] element using System.Runtime.Serialization; ... [Serializable] public class MyClass() { } using System.Runtime.Serialization; ... [Serializable] public class MyClass() { }

46 Interfészek Kizárólag absztrakt (megvalósítás nélküli) műveleteket tartalmazó típus Csak metódus-szignatúrákat tartalmazhatnak! Nem példányosíthatók – De egy interfészt megvalósító objektumra lehet interfészként hivatkozni Egy osztály akárhány interfészt megvalósíthat Minta az interfészt megvalósító osztályok számára Az interfész egy olyan absztrakt típus, amely az azt megvalósító osztályok objektumain végezhető közös műveleteket definiálja. Azaz az ezen osztályok közös viselkedését írja le (rögzíti a követelményeket). interface Síkidom { double Kerület(); double Terület(); }

47 Fontosabb .NET Interfészek
Leírás IComparable Az interfészt implementáló osztályok objektumainak rendezését teszi lehetővé IDisposable A manuális felszabadítást teszi lehetővé az implementáló osztályokban IConvertible Az implementáló osztály objektumainak alaptípusra való konverzióját teszi lehetővé ICloneable Az implementáló osztály objektumainak másolását teszi lehetővé IEquatable Az egyenlőség vizsgálatát teszi lehetővé az implementáló osztályokban IFormattable Az implementáló osztály objektumainak formázott szövegre való konverzióját teszi lehetővé

48 demo interface ILeanyzo { bool IsTudFozni(); int GetKor();
int GetFizetes(); }

49 Események Olyan üzenet, amelyet egy objektum küld egy másiknak egy adott esemény bekövetkezése esetén Az event kulcsszó vezeti be. (Valójában egy Delegate van mögötte) A paramétereket ajánlott EventArgs leszármazott formájában átadni Az eseményt előidézheti A felhasználó Valamely program Az eseménykezelés mechanizmusa delegáltak használatára épül. A delegate nem más mint referencia egy metódusra. (Típus biztos funkció pointer) A modell szerint az eseményt küldő objektum nem tudja, hogy melyik objektum fogja kezelni azt.

50 Delegáltak A delegate referencia egy metódusra. (Típus biztos funkció pointer) A delegate kulcsszó vezeti be. A delegált és a hivatkozott metódus visszatérési értékének és paramétereinek egyezniük kell class Piano { public void StartMozart() { ... } } ... public delegate void PlayCallback(); PlayCallback callback; Piano piano = new Piano() callback = new PlayCallback(piano.StartMozart); callback();

51 Definiálás Feliratkozás Feliratkozottak értesítése
Események használata Definiálás Feliratkozás Feliratkozottak értesítése public delegate void PlayCallback(); private event PlayCallback MozartStarted; Listener lis = new Listener(); MozartStarted += new PlayCallback(lis.Listen); public void StartMozart() { if (MozartStarted != null) { MozartStarted(); }

52 demo class Program { public delegate void MethodDelegate();
static void Main(string[] args) //DateTime start1 = DateTime.Now; //Method1(); //DateTime end1 = DateTime.Now; //Console.WriteLine("1 metódus lefutott:"+(end1 - start1).TotalMilliseconds.ToString()); //DateTime start2 = DateTime.Now; //Method2(); //DateTime end2 = DateTime.Now; //Console.WriteLine("2 metódus lefutott:"+ (end2 - start2).TotalMilliseconds.ToString()); RunMeasure(new MethodDelegate(Method1), "1"); RunMeasure(new MethodDelegate(Method2), "2"); Console.ReadLine(); } public static void RunMeasure(MethodDelegate mt, string methodName) DateTime start1 = DateTime.Now; mt(); DateTime end1 = DateTime.Now; Console.WriteLine(methodName + " metódus lefutott:" + (end1 - start1).TotalMilliseconds.ToString()); public static void Method1() Thread.Sleep(1000); Console.WriteLine("1 metódus"); public static void Method2() Thread.Sleep(2000); Console.WriteLine("2 metódus");

53 Névterek A típusok csoportosításának eszköze
A namespace nyelvi kulcsszóval definiálható namespace Geometria { class Síkidom } class Kör A névtér megadása nem kötelező.

54 Generikus típusok Olyan típus, amely definíciójában valamely típusnév paraméter formájában szerepel (típusparaméter) Az objektumreferencia deklarációjában kell meghatározni a típusparaméter helyébe behelyettesítendő konkrét típust (típuspéldányosítás) A típusparaméterre megszorítások tehetők, így csak a megfelelő típusokkal végezhető el a típuspéldányosítás A generikus típusok használata kevesebb futás-idejű hibát eredményezhet, és hatékonyabb kódhoz vezethet.

55 demo Generikus Típus DEMO class Program {
static void Main(string[] args) Obj ojektum = new Obj("Hello", " Pécs"); Console.WriteLine((string)ojektum.t + (string)ojektum.u); Gen<string, string> gen = new Gen<string, string>("Hello ", "Pécs"); Console.WriteLine(gen.t + gen.u); //Obj ojektum2 = new Obj(10.210, "Hello"); //Console.WriteLine((double)ojektum2.t + " " + (int)ojektum2.u); //Dobjon hibát forditasi időben Gen<string, double> gener = new Gen<string, double>("Hello", 21.10); Console.WriteLine(gener.t + gener.u); } class Obj public object t { get; set; } public object u { get; set; } public Obj(object _t, object _u) t = _t; u = _u; class Gen<T, U> public T t { get; set; } public U u { get; set; } public Gen(T _t, U _u)

56 Érték típusok Nyelvi elemek Programozói típusok Referencia típusok
Tematika Érték típusok Nyelvi elemek Programozói típusok Referencia típusok Osztályok Típus konverzió C# 3.0 Egy rövid áttekintőt fog adni az alábbi fejezetekről. Úgy mint a saját típusok készítése, típus konverziók stb.

57 Kétféle konverziós lehetőség: Implicit (automatikus) konverzió
Típuskonverzió Fejlesztés során gyakori scenario, hogy típusok között konverziót végezzünk. Kétféle konverziós lehetőség: Implicit (automatikus) konverzió Explicit (erőltetett) konverzió Az implicit típuskonverzió automatikusan megtörténik a program futása során, ahol szükség van a konverzióra és ez lehetséges. Az explicit típuskonverzióhoz jelezni kell a kódban, hogy melyik objektumot milyen típusra kell konvertálni.

58 Automatikusan végbemegy Nem kell jelölni Nem dobhat kivételt
Implicit konverzió Automatikusan végbemegy Nem kell jelölni Nem dobhat kivételt Bővítő konverzióknál automatikus Csak olyan típusok között van rá lehetőség, ahol a forrás típus minden elemének megfelelhető az új típus egy eleme Definiálhatunk saját implicit konverziós operátorokat

59 Explicit konverzió A kódban jelezni kell a konverziós szándékot
InvalidCastException –t dobhat Megoldható: Convert osztály statikus műveleteivel type cast operátorral A ToString() művelet felüldefiniálásával A Parse() művelet felüldefiniálásával A TryParse() művelet felüldefiniálásával Definiálhatunk saját explicit konverziós operátorokat

60 Boxing / Unboxing Boxing: értéktípus -> referenciatípus Ha egy értéktípusú változót referencia típusúként használunk, dobozolásra kerül sor Unboxing: referenciatípus -> értéktípus Az un/boxing lassít, kerülendő! -> Generics!

61 Az as operátor Átalakítja az objektumot, ha nem tudja, null-t ad vissza – nincs kivétel!

62 Lab Foundamental

63 Érték típusok Nyelvi elemek Programozói típusok Referencia típusok
Tematika Érték típusok Nyelvi elemek Programozói típusok Referencia típusok Osztályok Típus konverzió C# 3.0 Egy rövid áttekintőt fog adni az alábbi fejezetekről. Úgy mint a saját típusok készítése, típus konverziók stb.

64 A C# evolúciója C# 3.0 C# 2.0 C# 1.0 Nyelvbe ágyazott lekérdezések
.NET CLR C# 2002 1.0 2003 1.1 2005 2.0 2006 3.0 2007 3.5 C# 3.0 Nyelvbe ágyazott lekérdezések C# 2.0 Típusbiztosabb, hatékonyabb nyelv Generikus típusok, yield return A C# 1.0 megjentek a propertyk A C# 2.0 Generikus típusokkal hatékonyságot növeljük. Hisz kevesebb memóriát eszik az alkalmazásunk, a fordítás idejű hibákat kiszűrjük. Nincs Boxing se unboxing, így memória barát is. A C# 3.0 előzetes specifikációja már 2005-ben megjelent. Delphi és C# Anders Hejlsberg C# 1.0 Komponensek felügyelt környezetben Property, delegate, event

65 demo Yield returnnél folytatja a forciklust. Speciális metódus \gy, hisz megszakítjuk az adott metódus működését. Az iteráló változó értéke megmarad. class ListA<T> :IEnumerable<T> { T[] data = new T[10]; int count = 0; public void Add(T item) data[count++] = item; } #region IEnumerable<T> Members public IEnumerator<T> GetEnumerator() //folytatja a működését for (int i = 0; i < count; i++) yield return data[i]; #endregion #region IEnumerable Members System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() throw new NotImplementedException(); class Program static void Main(string[] args) ListA<string> list = new ListA<string>(); list.Add("1"); list.Add("2"); foreach (string item in list) Console.WriteLine(item);

66 Egyszerűsíti a tulajdonságok létrehozását Code Snippet: prop tab tab
Automatikus tulajdonságok Egyszerűsíti a tulajdonságok létrehozását Code Snippet: prop tab tab Kell a get és a set rész is. Nem hagyható el! ”ReadOnly-ság hoz, set –et állítsuk privátra. private string name; public string Name { get { return name; } set { name = value; } } Tulajdonságok? Gyakran készítünk tulajdonságokat, és ezt most már sokkal könnyebben tudjuk létrehozni.. public string Name { get; set; } //Read Only public string Name { get; private set; }

67 demo DEMO: Automatikus tulajdonság és reflector private string neve;
public string Neve { get return this.neve; } set neve = value; public string Nev { get; set; } public int Magassag { get; set; } public int MyProperty { get; set; }

68 Objektum és gyűjtemény inicializálása – A múlt
Ha egy osztályból szeretnénk egy példányt létrehozni, megfelelő paraméterekkel, akkor szükségünk volt egy megfelelően felparaméterezett konstruktorra. Ha a konstruktor nem volt képes minden számunkra szükséges tagváltozót beállítani, akkor kénytelenek voltunk property-k segítségével megtenni azt. C# 2.0 C# 3.0 Default Constructor kell. Az első példában az összes tagváltozónak értéket adtunk. Tulajdonképpen a háttérben az object initializer implicit módon meghívta a default konstruktort, ezt követően beállította a mezők értékeit. A példányosítás során kapcsos zárójelek között kell megadni a mezőneveket, az értékadásokat, vesszővel felsorolva. A második példában látható, hogy csak két tagváltozót állítunk be, az "Author" mező üresen marad. A harmadik példában expliciten meghívjuk a nem default konstruktort.

69 Objektum és gyűjtemény inicializálása
Mezők és tulajdonságok beállítása Nem kötelező minden mezőt kitölteni Paraméter nélküli konstruktornál a zárójel sem kell Nagyon kényelmes  Ebben az esetben a Default konstrokturt meghívja. Az inicializálás először egy rejtett változóba történik, és amikor az osztály kész van, akkor valósul meg az igazi értékadás. Ez a technika nagymértékben növeli a kód olvashatóságát és komoly rugalmasságot csempész bele. Az object initializerek segítségével értelemszerűen csak publikus tagváltozók és property-k állíthatók be. Music b=new Music{ Title=„Coldplay",Length=591 } Music b0=new Music(); b0.Title="Soul Bop"; b0.Length=591;

70 demo static void Main(string[] args) {
TestClass ts = new TestClass(1); ts.City = "Pécs"; //ts.MyID = 2; ts.Name = "Ference"; Console.WriteLine(ts); TestClass tx = new TestClass(2) { Name = "Attila", City = "Budapest" }; Console.WriteLine(tx); } class TestClass public int MyID { get; private set; } public string Name { get; set; } public string City { get; set; } public TestClass(int id) MyID = id; public override string ToString() return MyID + "\t" + Name + "\t" + City;

71 Publikus statikus függvény, statikus osztályban
Bővítő metódusok Meglévő osztályokat tudunk kiterjeszteni a segítségével. (Származtatás nélkül) Létrehozása: Publikus statikus függvény, statikus osztályban Az első paraméter a bővítendő osztály típusa Megelőzi a ”this” kulcsszó Csak publikus adattagokhoz fér hozzá Tegyük fel, hogy van egy A osztályunk. Szeretnénk kibővíteni a képességeit azáltal, hogy megírunk egy-két plussz függvényt hozzá. Ha nem tudunk hozzáférni, az A osztály kódjához, mert mondjuk csak egy DLL-ben áll rendelkezésünkre, akkor a OO paradigma szerint a természetes lépés, hogy származtatunk belőle egy B osztályt, és odapakoljuk az új függvényeinket. Nade mi történik akkor. ha az osztályt a készítője ellátta a sealed kulcsszóval? Akkor bizony nincs származtatás! Nem hagytak nekünk más választást, mint szögre akasztani OO elveinket és kétségbe esésünkben definiálni egy statikus osztályt, amiben elhelyezzük a statikus függvényeinket, melyek paraméterként kaphatják az A osztály egy példányát. Hát érezzük, hogy ez minden csak nem az igazi. Nem kapcsolódik a függvényünk az osztályhoz, senki más nem fog tudni a függvényeinkről (nincs intellisense), stb... Pedig nem járunk messze a megoldástól, első pillantásra a bővítő függvények is valami ilyesmit csinálnak. ------ Gyakran találkozunk azzal, hogy egy osztály metódusát ki szeretnénk terjeszteni saját funkcionalitással, de magához az osztályhoz nem férünk hozzá. Ilyenkor készítünk egy statikus osztályt és magunknak megírjuk az összehasonlítást. Igen ám de ez nem a legelegánsabb az Extension methodokkal meglévő osztályokat egészíthetünk ki egyszerűen és a Studio is észleli és segít a használatában. ---- Bővítő függvények készítésekor az első paraméter-t megelőzi a this kulcsszó, ezzel jelezvén, hogy az első paraméterként megjelölt típus nem más, mint az a típus, amit kiterjeszt! A compiler fordításkor átnézi az összes statikus osztályt bővítő függvények után kutatatva, és fordítás időben elvégzi a szükséges kiterjesztéseket. Érték és referencia típusokat is egyaránt bővíthetünk. Az ajánlás szerint érdemes egy külön namespace-ben egy statikus osztályba pakolni az ilyen bővítő függvényeket, és inkább usingolni a namespace-t a projektünkben. Maga a System.Linq névteret is ha usingoljuk a tömbök extra funkcionalitást kapnak. Tudunk rájuk szűrni egyszerűen, aggregációkat végezhetünk stb. Gondoljunk csak bele, hogy új funkcionalitással látnánk el egy eddig megírt osztályt, de valahogy úgy, hogy ne írjunk a kódjába, hisz problémát okozhat a visszafelé kompatibilitás. Ugyan ez volt a .NET esetén is. Csináljunk új funkciókat amire szüksége lehet a fejlesztőknek. Igen ám de ha belepiszkálunk a kódba akkor lábon lövik magukat és új verziót kell kiadni és az visszafelé nem lesz kompatibilis.ű

72 demo public static class ExtTest {
public static void ChangeNameToOther(this TestClass tx_in, string newName_in) tx_in.Name = "New name:" + newName_in; } public static void WriteToColorConsole(this object o, ConsoleColor c) Console.ForegroundColor = c; Console.WriteLine(o);

73 Implicit típusú lokális változók
Nem kell kiírni a lokális változó típusát A változó típusa a jobb oldali kifejezés típusa lesz var == a jobboldal típusa Továbbra is erősen típusos! A fordító kitalálja a környezetből hogy milyen típusú egy lokális változó var list = new List<string>();

74 demo var x = 10; var w = 21f; var lista = new List<int>();
var text = new Dictionary<int, List<string>>();

75 Olyan, mint a névtelen metódus, csak tömörebb és kifejezőbb
Lambda kifejezések => operátor Olyan, mint a névtelen metódus, csak tömörebb és kifejezőbb Alapvetően egy sokkal kényelmesebb és érthetőbb szintaxis-t bocsátottak rendelkezésünkre, aminek segítségével névtelen függvényeket készíthetünk. Nézzük meg ugyanarra a feladatra, mindkét variációt: Az első esetben a Where függvény paramétereként egy delegate-et(lényegében függvénypointert) adunk át és azt a kódot, amire mutat, rögtön definiáljuk is. Ugye ez a C# 2.0-ban bevezetett névtelen metódus. Ugye az történik, hogy minden listaelemre (adatbázisosan gondolkodva, "minden sorra") meghívjuk ezt a kódrészletet, ami akkor tér vissza igazzal, ha a szerző " John Steinbeck". A második esetben lambda kifejezést használtunk. Azt mondtuk, hogy csak azok a "b"-k (Book példányok) érdekelnek, melyekre igaz az, hogy az "Author"-juk "John Steinbeck". Tehát a szintaxis lényegében a következő: paraméterek => kifejezés Ami feltűnhet, hogy explicite nem adtuk meg "b" típusát. Ezt a fordító találta ki a Where bővítő metódus alapján. Természetesen explicite is meg lehet határozni a típust: A fogalom a Church és Kleene által a 30-as években bevezetett lambda kalkulusfogalmán alapszik. Church és Kleene rámutatott, hogy a számítógépes nyelvekben megfogalmazható kifejezések mindegyike leírható az ún. lambda kalkulussal, azaz minden kifejezés helyettesíthető egy olyan függvénnyel, amely egyetlen bemenő paramétert fogad. Ennek a függvénynek az egyetlen bemenő paramétere és az értéke is egy olyan függvény, amely szintén egyetlen bemenő paramétert fogad. Erre a függvényre, annak bemenő paraméterére és értékére ezt a fajta definíció a végtelenségig alkalmazhatjuk rekurzívan. A lambda kalkulus jelentőségét az adja, hogy nem kevesebbet mond, mint azt, hogy minden olyan kifejezés (figyelem, nem művelet!), amit a programozási nyelvekben használunk, leírható „egyszerű” függvények alkalmazásával. Itt az „egyszerű” olyan függvényt jelent, amelynek nincsen mellékhatása (azaz programozási nyelvek irányából megfogva: csak lokális, a függvény belsejében lévő változókat módosít, a függvény külső környezetét pl. az abban lévő változókat nem módosítja). A C# 3.0-ban ezek a funkciók a Delegate-eken és az Anonymous típusokon alapulnak melyek már a C# előző változataiban is megtalálhatóak voltak. Tulajdonképpen Névtelen metódusok még tömörebb és egyszerübb szintaktikával. Új operátor ez pedig az => .A jobb oldalra nem feltételnül egy

76 Névtelen metódusok még rövidebb szintaktikával
Lambda kifejezések Névtelen metódusok még rövidebb szintaktikával delegate( string s ) { return s.StartsWith( "S" ); } Ugyanaz mint: s => s.StartsWith( "S" ) ‘s’ típusát kitalálja a környezetből! Több paraméter esetén a szintaktika ( x, y ) => Math.Sqrt( x * x + y * y ) Névtelen metódusok. Metódusokat illetve funkciókat írjunk le vele amit egyszer használunk, és ezekre értelemszerűen nem tudunk majd máshonnan ráhivatkozni. Tulajdonképpen Névtelen metódusok még tömörebb és egyszer Kódot adunk át egy metódus paraméterekéntübb szintaktikával. Új operátor ez pedig az => .

77 demo Dictionary<int, string> dr = new Dictionary<int, string> { { 1, "maci" }, { 2, "maci" }, { 3, "macska" } }; var c= dr.Where(d => d.Value == "maci"); var c = lista.Where(l => l == 1); foreach (var item in c) { Console.WriteLine(item.Key); }

78 Visual Studio "Orcas" Konferencia
Anonymous Types 2007. május 24., Budapest Lurdy Ház C# 3.0 –tól létrehozhatunk Anonymous típusokat. Legnagyobb előnye Linq lekérdezéseknél lehet. Segítségével nem kell segédosztályt definiálnunk, a compiler elkészítette nekünk. Nincs szükség fölösleges többlet munkára. {Name = "<>f__AnonymousType0`2" FullName = "<>f__AnonymousType0`2[[System.String, mscorlib, Version= , Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32, mscorlib, Version= , Culture=neutral, PublicKeyToken=b77a5c561934e089]]"} Láthatjuk, hogy a var micsoda nagy segítséget nyújt számunkra. Nélküle ugyanis lehetetlen lenne az anonim típus használata. Hiszen milyen típusú változónak tudnánk értékül adni? (object már kasztolás) A var-ként definiált változó implicit módon felveszi ezt az anoním típust, és úgy használhatjuk, mint bármely hagyományos osztálypéldányt. A var-ként deklarált anonymousType változó felveszi ezt az anoním típust. A compiler a következő típust készíti el nekünk. I MSDN Kompetencia Központ (http://www.devPORTAL.hu)

79 Visual Studio "Orcas" Konferencia
Anonymous Types 2007. május 24., Budapest Lurdy Ház var list = new [ ] { new { Title = "Soul Bop", Length = 591 }, new { Title = "Hangin' in the City", Length = 397 } }; foreach( var x in list.Filter( s => s.Length < 300 ) ) Console.WriteLine( x ); Az osztály az inicializáláskor kapott tagokat kapja Tulajdonságok ToString(), Equals( object ), GetHashCode() Azonos típus- és névsorrend ugyanazt a típust hivatkozza Egyszer használunk, és ezekre értelemszerűen nem tudunk majd máshonnan ráhivatkozni. Kódot adunk át egy metódus paramétereként MSDN Kompetencia Központ (http://www.devPORTAL.hu)

80 demo var list = new { Title = "Cimem", Address = "Marti" };
Console.WriteLine(list.Address);

81 Visual Studio "Orcas" Konferencia
Partial Methods 2007. május 24., Budapest Lurdy Ház A C# 2.0 -ban megismert partial class képességeit bővíti ki. (Az osztályok kódját szétszórhattuk több forrásfájlba, és ha mindkét helyen megjelöltük classunkat a partial kulcsszóval, akkor a fordító szépen összefésülte őket.) C# 3.0 –tól megjelölhetünk metódusokat is a parital kulcsszóval. A fordító, ahogy a parciális osztályokat a parciális osztályokat és azok hívásait is összefésüli. // Developer-written part: public partial class PartialExampleType { partial void PartialMethod() Console.WriteLine("PartialMethod (\"{0}\") called."); } // Auto-generated part: public partial class PartialExampleType { public void GeneratedMethod() Console.WriteLine("GeneratedMethod() calls PartialMetod()"); PartialMethod(); } partial void PartialMethod(); MSDN Kompetencia Központ (http://www.devPORTAL.hu)

82 Visual Studio "Orcas" Konferencia
Partial Methods 2007. május 24., Budapest Lurdy Ház Nem muszáj megvalósítani. Ha nem valósítjuk meg a parciális metódust, a fordító nem fordítja be a hívást. // Auto-generated part: public partial class PartialExampleType { public void GeneratedMethod() Console.WriteLine("GeneratedMethod() calls PartialMetod()"); PartialMethod(); } partial void PartialMethod(); Ha egy kicsit más megközelítésből vizsgáljuk a parciális metódusokat - nevezetesen, hogy mégis, mire jók -, azt látjuk, hogy a kódgenerátoroknak lehetőségük van nem csak effektív kód generálására, hanem egyfajta metódus-templatek definiálására, illetve ezen template-ek hívásának beépítésére a generált kódba - mi pedig a parciális osztály ránk eső részében vagy kitöltjük ezeket az "üres templateket", vagy nem. // Developer-written part: public partial class PartialExampleType { partial void PartialMethod() Console.WriteLine("PartialMethod (\"{0}\") called."); } MSDN Kompetencia Központ (http://www.devPORTAL.hu)

83 © 2006 Microsoft Corporation. All rights reserved
© 2006 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries. The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.


Letölteni ppt "Framework fundamentumok"

Hasonló előadás


Google Hirdetések