1 / 33

RP3/predavanje09

RP3/predavanje09. Imenički prostori Anonimni tipovi i metode Lambda izrazi LINQ Finalizatori. Imenički prostori. Imenički prostor (engl. namespace ) je područje unutar kojeg svako ime tipa mora biti jedinstveno.

Download Presentation

RP3/predavanje09

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. RP3/predavanje09 • Imenički prostori • Anonimni tipovi i metode • Lambda izrazi • LINQ • Finalizatori ---------- Računarskipraktikum 3 ---------- Maja Starčević

  2. Imenički prostori Imenički prostor (engl. namespace) je područje unutar kojeg svako ime tipa mora biti jedinstveno. Tipovi su organizirani u hijerarhijske imeničke prostore. Imenički prostori nemaju utjecaj na vidljivost članova. Za tipove koji nisu smješteni ni u jednom imeničkom prostoru kaže se da se nalaze u globalnom imeničkom prostoru koji sadrži sve najviše rangirane imeničke prostore. -------Računarski praktikum 3-------

  3. Imenički prostori namespace Outer { namespace Middle { namespace Inner { class Class1 { … } class Class2 { … } } } } namespace Outer.Middle.Inner { class Class1 { … } class Class2 { … } } Pozivanje klase Outer.Middle.Inner.Class1 -------Računarski praktikum 3-------

  4. Imenički prostori Da bismo naznačili da se ime nalazi u globalnom prostoru imena, koristimo ključnu riječ global. global::System.Drawing.Color color; Napomena: deklaracija nekog prostora imena se može ponoviti više puta. Bitno je da te deklaracije ne sadrže tipove s istim imenom. -------Računarski praktikum 3-------

  5. Imenički prostori Možemo i koristiti drugo (kraće) ime za neki prostor. using DrawingColor=System.Drawing.Color; class Program { DrawingColor color; } Pomoću using možemo zadati i kraće ime za neki tip. Ne moramo dakle uključiti cijeli prostor System.Text. using StringBuilder=System.Text.StringBuilder; -------Računarski praktikum 3-------

  6. Imenički prostori usingSystem; namespaceSystem { namespaceSystem { class Console { void f() { }} class Program { staticvoidMain(string[] args) { Console.WriteLine( “Hello!”); System.Console.WriteLine("Hello!"); System.System.Console.WriteLine("Hello!"); } } } } Primjer 1: Koji je poziv funkcije WriteLine korektan? -------Računarski praktikum 3-------

  7. Imenički prostori using System; namespace System // ovaj prostor je već prethodno definiran { (ovdje se nalazi klasa Console koju smo dosad koristili) namespace System // ovaj prostor smo sami definirali { class Console { void f() { } } class Program { static void Main(string[] args) { Console.WriteLine( “Hello!”); // greška System.Console.WriteLine("Hello!"); //greška System.System.Console.WriteLine("Hello!"); //greška global::System.Console.WriteLine( “Hello!”); // u redu } } } } -------Računarski praktikum 3-------

  8. Verzija C# 3.0 Od ove verzije dostupni su i sljedeći elementi programa: • Lambda izrazi • Metode proširenja • Implicitno dodjeljivanje tipova • Prepoznavanje upita • Anonimni tipovi • Implicitno zadavanje polja • Inicijalizacija objekata i kolekcija • Automatski implementirana svojstva -------Računarski praktikum 3-------

  9. Anonimni tipovi Sljedeći primjer ćemo zapisati jednostavnije, pomoću anonimnih tipova: class Program { public delegate int Delegat(int i); static public int sqr(int a) { return a * a ; } static public void Main() { int j = 2; Delegat d = sqr; Console.Write(d(2)); } } -------Računarski praktikum 3-------

  10. Anonimni tipovi Jednostavnija verzija: class Program { public delegate int Delegat(int i); static public void Main() { Delegat d = delegate(int a) { return a * a; }; int j = 2; Console.Write(d(2)); } } -------Računarski praktikum 3-------

  11. Lambda izrazi Pomoću lambda izraza moguće je kod zapisati još jednostavnije: class Program { public delegate int Delegat(int i); static public void Main() { Delegat d = a => a*a; int j = 2; Console.Write(d(2)); } } -------Računarski praktikum 3-------

  12. Lambda izrazi Napomena: opća forma lambda izraza je: U prethodnom primjeru možemo pisati i: Delegat d = (int a) => a*a; ili bez eksplicitnog navođenja tipova, i bez zagrada (kad se radi o samo jednom parametru) Delegat d = a => {return a*a; }; (popis parametara) => izraz ili blok naredbi -------Računarski praktikum 3-------

  13. Func i Action delegati U prostoru System definirano je više (preopterećenih) generičkih delegata s imenom Func i Action, npr.: delegate TResult Func<TResult> (); delegate TResult Func <T, TResult>(T arg1); itd. delegate void Action(); delegate void Action<T1, T2>(T1 arg1, T2 arg2); itd. -------Računarski praktikum 3-------

  14. Func i Action delegati Koristeći tako definirane generičke delegate, prethodni kod možemo pisati na još jednostavniji način: Func<int, int> sqr = x => x * x; Console.WriteLine(sqr(2)); -------Računarski praktikum 3-------

  15. Metode proširenja Ukoliko želimo dodavati metode u već definiranu klasu, a modifikacija klase nije dozvoljena ili je zapečaćena pa se ne može ni nasljeđivati, možemo to učiniti pomoću metoda proširenja. Ako je klasa definirana pomoću modifikatora partial, možemo dodati metodu i u drugi dio klase. Metoda proširenja je statička metoda (negeneričke) statičke klase. Sama metoda može biti generička. Na prvi parametar takve metode je potrebno primijeniti modifikator this. -------Računarski praktikum 3-------

  16. Metode proširenja public class DPoint { public double x, y; public DPoint(double _x, double _y) { x = _x; y = _y; } } public static class DodatneMetode { public static double Udaljenost(this DPoint cp1, DPoint cp2) { return Math.Sqrt(Math.Pow(cp1.x - cp2.x,2) + Math.Pow(cp1.y - cp2.y, 2)); } } -------Računarski praktikum 3-------

  17. Metode proširenja class Program { staticvoidMain(string[] args) { DPoint p1 = new DPoint(2, 4); DPoint p2 = new DPoint(6, 1); Console.WriteLine(p1.Udaljenost(p2)); // ili… Console.WriteLine(DodatneMetode.Udaljenost(p1, p2)); } } -------Računarski praktikum 3-------

  18. Implicitno zadavanje polja var studenti = new[] { new { Ime="Petar", Prezime="Peric“ }, new { Ime="Karlo", Prezime="Karlovic“ } }; foreach (var student in studenti) Console.WriteLine(student.Ime); U sljedećem primjeru imamo polje koje sadrži objekte anonimnog tipa. Umjesto tipa polja, navodimo var. -------Računarski praktikum 3-------

  19. LINQ U LINQ-u pod nizom smatramo objekt tipa koji implementira generičko IEnumerable sučelje. Operator upita je metoda koja transformira niz. Operatori upita se nalaze u statičkoj klasi Enumerable (nalazi se u prostoru System.Linq). Radi se o statičkim generičkim metodama koje su zapravo metode proširenja za klase tipa IEnumerable<>. Primjer: metoda Where pomoću koje iz početnog niza dobivamo podskup s određenim svojstvima koje smo zadali lambda izrazom. public static IEnumerable<TSource> Where<TSource> ( this IEnumerable<TSource> source, Func<TSource, bool> predicate ) -------Računarski praktikum 3-------

  20. LINQ S obzirom da radimo s metodama proširenja, možemo ih pozivati na dva načina. string[] imena = { "Mirko", "Marko", "Mario", "Karlo", "Marina", "Ivona" }; IEnumerable<string> imenaKojaPocinjuNaMa = System.Linq.Enumerable.Where(imena, n => n.StartsWith("Ma")); /* ili IEnumerable<string> imenaKojaPocinjuNaMa = imena.Where(n => n.StartsWith("Ma")); */ foreach (string ime in imenaKojaPocinjuNaMa) Console.WriteLine(ime); -------Računarski praktikum 3-------

  21. LINQ Pomoću metode Select transformiramo svaki element početnog niza po pravilu zadanom lambda izrazom. int[] brojevi = new int[] { 1, 2, 3, 4, 5 }; IEnumerable<int> dvostrukiBrojevi= brojevi.Select(n => n * 2); foreach (int i in dvostrukiBrojevi) Console.Write("{0} ", i); // 2 4 6 8 10 -------Računarski praktikum 3-------

  22. LINQ Nizove možemo mijenjati koristeći lambda sintaksu koju smo vidjeli u prethodnim primjerima ili sintaksu upita ili u nekim slučajevima njihovu kombinaciju. Zapisat ćemo prvi primjer u drugoj sintaksi. string[] imena = { "Mirko", "Marko", "Mario", "Karlo", "Marina", "Ivona" }; IEnumerable<string> imenaKojaPocinjuNaMa = from n in imena where n.StartsWith("Ma") select n; foreach (string ime in imenaKojaPocinjuNaMa) Console.WriteLine(ime); -------Računarski praktikum 3-------

  23. LINQ using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; class Program { static void Main(string[] args) { string[] rijeci = { "kap", "vrt", "krt", "pol", "krv" }; IEnumerable<string> rijeciBezSamoglasnika = from n in rijeci let rijecBezSamoglasnika = Regex.Replace(n, "[aeiou]", "") where n == rijecBezSamoglasnika select n; foreach (string rijec in rijeciBezSamoglasnika) Console.WriteLine(rijec); } } S ključnom riječi let uvodimo novu varijablu. vrt krt krv -------Računarski praktikum 3-------

  24. LINQ Upit može sadržavati više from iskaza, koji onda funkcioniraju poput ugniježdene petlje. char[] slova = { 'a', 'b', 'c' }; int[] brojevi = { 1, 2, 3, }; IEnumerable<string> clanovi = from n in slova from m in brojevi select n + m.ToString(); foreach (string s in clanovi) Console.Write(s + " "); a1 a2 a3 b1 b2 b3 c1 c2 c3 -------Računarski praktikum 3-------

  25. LINQ Mnogi operatori upita funkcioniraju tako da se ne izvršavaju pri kreiranju, nego kad se na enumeratoru rezultata pozove metoda MoveNext (npr. kad u sljedećem primjeru prođemo kroz niz s foreach). char[] slova = { 'a', 'b', 'c' }; List<int> brojevi = new List<int>{ 1, 2, 3, }; IEnumerable<string> clanovi = from n in slova from m in brojevi select n + m.ToString(); brojevi.Add(4); foreach (string s in clanovi) Console.Write(s + " "); a1 a2 a3 a4 b1 b2 b3 b4 c1 c2 c3 c4 -------Računarski praktikum 3-------

  26. Destruktor (metoda Finalize) Implementacija destruktora u klasi je zapravo nadjačavanje object.Finalize metode. Destruktori se mogu naći samo u klasama, strukture ih ne mogu sadržavati. -------Računarski praktikum 3-------

  27. Destruktor (metoda Finalize) class C { ~C() { // implementacija} } je zapravo kraći zapis za: class C { protected void override Finalize() { //implementacija; base.Finalize(); } } Napomena: kompilator dozvoljava samo prvi način zapisa. -------Računarski praktikum 3-------

  28. Dispose, Finalize Finalizator funkcionira slično destruktoru u C++-u s tom razlikom da se za upravljane resurse brine Garbage Collector te se finalizatori implementiraju jedino u slučaju da se moramo pobrinuti za uništavanje neupravljanih resursa. Finalizator se ne smije pozivati eksplicitno, njega će pozvati GC kad odluči uništiti objekt. Ukoliko ipak želimo neupravljane resurse uništiti čim prije, moramo implementirati metodu Dispose. Ukoliko, klasa implementira metodu Dispose, preporučljivo je da implementira IDisposable sučelje. -------Računarski praktikum 3-------

  29. Dispose, Finalize Sljedeći primjer daje standardni način pisanja Finalize metode u kombinaciji s Dispose metodom. Klasa C implementira Dispose u dvije preopterećene varijante. Javna metoda void Dispose() je namijenjena za korisnike, njome se naređuje što prije uništavanje neupravljanih resursa. I ta metoda i finalizator se baziraju na void Dispose (bool) metodi. Dispose(true) se poziva u javnoj Dispose metodi, a Dispose(false) u finalizatoru. Dakle, čišćenje objekta teče na isti način. -------Računarski praktikum 3-------

  30. Dispose, Finalize Preko bool disposing dakle samo kontroliramo je li pozvan finalizator (naravno implicitno) ili Dispose metoda. Osigurač bool is_disposed sprječava višestruko izvršavanje Dispose metode, odnosno dozvoljava da ju korisnik može više puta pozivati na istom objektu, ali da se samo prvi put dogodi čišćenje. Ukoliko je pozvana Dispose metoda, GC neće pozivati finalizator što se postiže pozivom GC.SupressFinalize metode. -------Računarski praktikum 3-------

  31. Dispose, Finalize class C { bool is_disposed = false; protected virtual void Dispose(bool disposing) { if (!is_disposed) { if (disposing) { Console.WriteLine("Ovo je Dispose, a ne Finalize"); } //čišćenje objekta } is_disposed = true; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~C() { Dispose(false); Console.WriteLine("U finalizatoru smo"); } } -------Računarski praktikum 3-------

  32. Dispose, using U prethodnom kontekstu ključna riječ using ima novo značenje. Konkretno, kod using (C obj = new C()) { ……… } je ekvivalentan s: -------Računarski praktikum 3-------

  33. Dispose, Finalize C obj = new C(); try { ……….. } finally { if (obj != null) ((IDisposable)obj).Dispose(); } -------Računarski praktikum 3-------

More Related