Upload
ferris-copeland
View
44
Download
5
Embed Size (px)
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(); }