RP3/predavanje09

Preview:

DESCRIPTION

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. - PowerPoint PPT Presentation

Citation preview

---------- Računarski praktikum 3 ----------Maja Starčević

124/04/23

RP3/predavanje09

Imenički prostori Anonimni tipovi i metode Lambda izrazi LINQ Finalizatori

-------Računarski praktikum 3------- 224/04/23

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------- 324/04/23

Imenički prostori

namespace Outer{ namespace Middle { namespace Inner { class Class1 { … } class Class2 { … } } }}

namespace Outer.Middle.Inner{ class Class1 { … } class Class2 { … } }

Pozivanje klaseOuter.Middle.Inner.Class1

Imenički prostori

Da bismo naznačili da se ime nalazi u globalnom prostoru imena, koristimo ključnu riječ global.

-------Računarski praktikum 3------- 424/04/23

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.

Imenički prostori

-------Računarski praktikum 3------- 524/04/23

Možemo i koristiti drugo (kraće) ime za neki prostor.

using DrawingColor=System.Drawing.Color;

class Program { DrawingColor color; }

using StringBuilder=System.Text.StringBuilder;

Pomoću using možemo zadati i kraće ime za neki tip. Ne moramo dakle uključiti cijeli prostor System.Text.

Imenički prostori

-------Računarski praktikum 3------- 624/04/23

using System;

namespace System{ namespace System {

class Console { void f() { } }

class Program { static void Main(string[] args) { Console.WriteLine( “Hello!”); System.Console.WriteLine("Hello!"); System.System.Console.WriteLine("Hello!"); } } }}

Primjer 1:

Koji je pozivfunkcijeWriteLinekorektan?

Imenički prostori

-------Računarski praktikum 3------- 724/04/23

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------- 824/04/23

Verzija C# 3.0

Od ove verzije dostupni su i sljedeći elementi programa:

Lambda izraziMetode proširenjaImplicitno dodjeljivanje tipovaPrepoznavanje upitaAnonimni tipoviImplicitno zadavanje poljaInicijalizacija objekata i kolekcijaAutomatski implementirana svojstva

-------Računarski praktikum 3------- 924/04/23

Anonimni tipovi

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)); } }

Sljedeći primjer ćemo zapisati jednostavnije, pomoću anonimnih tipova:

-------Računarski praktikum 3------- 1024/04/23

Anonimni tipovi

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)); } }

Jednostavnija verzija:

-------Računarski praktikum 3------- 1124/04/23

Lambda izrazi

class Program { public delegate int Delegat(int i); static public void Main() {

Delegat d = a => a*a; int j = 2; Console.Write(d(2)); } }

Pomoću lambda izraza moguće je kod zapisati još jednostavnije:

-------Računarski praktikum 3------- 1224/04/23

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------- 1324/04/23

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------- 1424/04/23

Func i Action delegati

Koristeći tako definirane generičke delegate, prethodni kodmožemo pisati na još jednostavniji način:

Func<int, int> sqr = x => x * x;Console.WriteLine(sqr(2));

-------Računarski praktikum 3------- 1524/04/23

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------- 1624/04/23

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------- 1724/04/23

Metode proširenja

class Program{ static void Main(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------- 1824/04/23

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------- 1924/04/23

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------- 2024/04/23

LINQ

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);

S obzirom da radimo s metodama proširenja, možemo ih pozivati na dva načina.

-------Računarski praktikum 3------- 2124/04/23

LINQ

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

Pomoću metode Select transformiramo svaki element početnog niza po pravilu zadanom lambda izrazom.

-------Računarski praktikum 3------- 2224/04/23

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------- 2324/04/23

LINQusing 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); } }

vrtkrtkrv

S ključnom riječi let uvodimo novu varijablu.

-------Računarski praktikum 3------- 2424/04/23

LINQ

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

Upit može sadržavati više from iskaza, koji onda funkcioniraju poput ugniježdene petlje.

-------Računarski praktikum 3------- 2524/04/23

LINQ

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

Mnogi operatori upita funkcioniraju tako da se ne izvršavaju prikreiranju, nego kad se na enumeratoru rezultata pozove metoda MoveNext (npr. kad u sljedećem primjeru prođemo kroz niz s foreach).

-------Računarski praktikum 3------- 2624/04/23

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------- 2724/04/23

Destruktor (metoda Finalize)

class C{ ~C() { // implementacija}}

class C{ protected void override Finalize() { // implementacija; base.Finalize(); }}

je zapravo kraći zapis za:

Napomena: kompilator dozvoljava samo prvi način zapisa.

-------Računarski praktikum 3------- 2824/04/23

Dispose, Finalize

Finalizator funkcionira slično destruktoru u C++-u s tom razlikomda se za upravljane resurse brine Garbage Collector te se finalizatori implementiraju jedino u slučaju da se moramopobrinuti za uništavanje neupravljanih resursa.Finalizator se ne smije pozivati eksplicitno, njega će pozvati GCkad odluči uništiti objekt.Ukoliko ipak želimo neupravljane resurse uništiti čim prije,moramo implementirati metodu Dispose. Ukoliko, klasaimplementira metodu Dispose, preporučljivo je da implementiraIDisposable sučelje.

-------Računarski praktikum 3------- 2924/04/23

Dispose, Finalize

Sljedeći primjer daje standardni način pisanja Finalize metodeu 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------- 3024/04/23

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šavanjeDispose metode, odnosno dozvoljava da ju korisnik moževiše puta pozivati na istom objektu, ali da se samo prvi put dogodi čišćenje.

Ukoliko je pozvana Dispose metoda, GC neće pozivatifinalizator što se postiže pozivomGC.SupressFinalize metode.

-------Računarski praktikum 3------- 3124/04/23

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------- 3224/04/23

Dispose, using

using (C obj = new C( ) ) { ……… }

U prethodnom kontekstu ključna riječ using ima novo značenje.

Konkretno, kod

je ekvivalentan s:

-------Računarski praktikum 3------- 3324/04/23

Dispose, Finalize

C obj = new C(); try {

……….. } finally { if (obj != null) ((IDisposable)obj).Dispose(); }

Recommended