Računarski praktikum 3 Vježbe 07

Preview:

DESCRIPTION

Računarski praktikum 3 Vježbe 07. Vinko Petričević. Iznimke. Delegati i događaji. Iznimke. Dio programa u kojem očekujemo neku anomaliju Iznimka najčešće sadrži neku informaciju o anomaliji - PowerPoint PPT Presentation

Citation preview

Računarski praktikum 3Vježbe 07

Vinko Petričević

Iznimke. Delegati i događaji

Iznimke

Dio programa u kojem očekujemo neku anomaliju Iznimka najčešće sadrži neku informaciju o anomaliji Kada je iznimka “bačena” stog se odmotava i traži

se handler koji će ju obraditi. Ako ju nitko ne obradi, program se “ruši”

Iznimka može biti tipa System.Exception ili iz nekog tipa izvedenog iz njeg (npr. u imenskom prostoru System imamo ArgumentNullException, InvalidCastException, OverflowException…)

Iznimke

Iznimku generiramo ključnom riječi throw, a metoga za hvatanje iznimki počinje sa catch, koji uvijek dolazi u paru sa try

Unutar try bloka navedemo kritičan dio kôda (unutar kojeg bi se mogao desiti throw), a nakon toga slijedi catch blok koji eventualnu iznimku obrađuje

Generiranje iznimkeclass Program{

static void Main(string[] args){

Console.WriteLine("Ulaz u Main...");f1();Console.WriteLine("Main izvršena.");

}static void f1(){

Console.WriteLine("Ulaz u f1...");f2();Console.WriteLine("f1 izvršena.");

}static void f2(){

Console.WriteLine("Ulaz u f2...");throw new System.Exception(); // izbacujemo iznimkuConsole.WriteLine("f2 izvršena.");

}}

Hvatanje iznimke...

static void f2(){

Console.WriteLine("Ulaz u f2...");try{

Console.WriteLine("Ulaz u try blok...");throw new System.Exception();Console.WriteLine("Izlaz iz try bloka...");

}catch{

Console.WriteLine("Iznimka uhvaćena i obrađena.");}Console.WriteLine("Izlaz iz f2.");

}

Zadatak

Izmijenite prethodni primjer, tako da se iznimka hvata u funkciji f1, te u main-u. Kometirajte što se mijenja

Namjenske iznimke Često imamo različiti kôd za obrađivanje

iznimaka različitog tipa. Osim takozvanog generičkoh catch bloka, možemo navesti tip iznimke koji on obrađuje (navodimo prvo specijalni tip)

try{

…}catch (System.DivideByZeroException) {

Console.WriteLine("Iznimka dijeljenja s nulom uhvaćena!");}catch (System.ArithmeticException) {

Console.WriteLine("Aritmetička iznimka uhvaćena!");}catch {

Console.WriteLine("Nepoznata iznimka uhvaćena!");}

Finally Ponekad želimo izvršiti dio koda bez obzira na

to da li se dogodila greška ili ne

Nakon eventualno obrađenih iznimaka, izvrši se finally blok

try{

…}catch {

…}finally {

Console.WriteLine(“Ovo se ce izvrsiti uvijek na kraju!");}

Finally Ponekad želimo izvršiti dio koda bez obzira na

to da li se dogodila greška ili ne

Nakon eventualno obrađenih iznimaka, izvrši se finally blok

try{

…}catch {

…}finally {

Console.WriteLine(“Ovo se ce izvrsiti uvijek na kraju!");}

System.Exception objekt Svojstvo Message je readonly, i postavlja se prilikom kreiranja

iznimke Svojstvo HelpLink se može i mijenjati i služi da se omogući vezu do

help datoteke sustava pomoći Svojstvo StackTrace se može samo čitati i njega automatski

postavlja .net framework

static double Podijeli(double a, double b) {if (b == 0) {

DivideByZeroException e = new DivideByZeroException();e.HelpLink = "http://www.math.hr"; // postavljamo HelpLinkthrow e;

}if (a == 0) {

// Message možemo postaviti jedino kroz konstruktorthrow new System.ArithmeticException("Nulu ne možete dijeliti!");}

return a / b;}…

System.ApplicationException Ako nam normalne iznimke nisu dobre, možemo samo napraviti

klasu (koja se najčešće izvodi iz ApplicationException), te u njoj možda dodati dodatne informacije o pogrešci

InnerException Ako nismo do kraja obradili iznimku, možemo ju proslijediti dalje na

obradu. U tom slučaju kreiramo iznimku, čije svojstvo InnerException postavimo na trenutnu iznimku, te ponovo bacimo tu novu iznimku

Delegati

nakon definiranja u njega možemo učahuriti bilo koju metodu s istim popisom parametara i povratnim tipom – slično kao pointeri na funkcije u C-u

[modifikator pristupa] delegate NazivDelegata(potpisMetode);

public delegate int KojiJePrvi(object o1, object o2);

Primjer 1

public class Osoba { public string ime, prezime; }

public delegate int usporedi(Osoba o1, Osoba o2);

class Program { public static int usporediPoImenu(Osoba o1, Osoba o2) { return o1.ime.CompareTo(o2.ime); } public static int usporediPoPrezimenu(Osoba o1, Osoba o2) { return o1.prezime.CompareTo(o2.prezime); } static void Main(string[] args) { usporedi u = new usporedi(usporediPoImenu);

Osoba o1, o2;...

if (u(o1, o2) > 0) { ... } } }

Višeodredišni delegati delegate možemo dodavati i oduzimati pomoću operatora + i –

(odnosno += i -=), te će se onda osim jedne, izvršiti sve funkcije koje su dodane

Primjer 2class KlasaSDelegatom {

// deklaracija delegatapublic delegate void StringDelegat(string s);

}

class ImplementirajucaKlasa {public static void ZapisiString(string s) {

Console.WriteLine("Zapisivanje niza znakova: {0}", s);}public static void ZabiljeziString(string s) {

Console.WriteLine("Bilježenje niza znakova: {0}", s);}public static void PosaljiString(string s) {

Console.WriteLine("Odašiljanje niza znakova: {0}", s);}

}

Primjer 2class Program { static void Main(string[] args) {

// definiramo tri delegata tipa StringDelegatKlasaSDelegatom.StringDelegat Zapisivac, Biljeznik, Odasiljac;

 // definiramo još jednog delegata tipa StringDelegatKlasaSDelegatom.StringDelegat ViseodredisniDelegat;

 // instanciramo tri delegataZapisivac = new KlasaSDelegatom.StringDelegat(

ImplementirajucaKlasa.ZapisiString);Biljeznik = new KlasaSDelegatom.StringDelegat(

ImplementirajucaKlasa.ZabiljeziString);Odasiljac = new KlasaSDelegatom.StringDelegat(

ImplementirajucaKlasa.PosaljiString); 

// pozivamo metodu delegata ZapisivacZapisivac("Niz znakova prosljeđen Zapisivaču");

// pozivamo metodu delegata BiljeznikBiljeznik("Niz znakova prosljeđen Bilježniku");

 // pozivamo metodu delegata OdasiljacOdasiljac("Niz znakova prosljeđen Odašiljaču");

Primjer 2 

Console.WriteLine("Viseodredisnidelegat = Zapisivac + Biljeznik");// kombiniramo dva delegata u ViseodredisniDelegatViseodredisniDelegat = Zapisivac + Biljeznik;

 // pozivamo 2 metode ViseodredisniDelegat-aViseodredisniDelegat("Prvi prosljeđeni niz znakova ");

 Console.WriteLine("Viseodredisnidelegat += Odasiljac");// dodajemo i treći delegat u ViseodredisniDelegatViseodredisniDelegat += Odasiljac;

// pozivamo 3 metode ViseodredisniDelegat-aViseodredisniDelegat("Drugi prosljeđeni niz znakova");

 Console.WriteLine("Viseodredisnidelegat -= Biljeznik");// oduzimamo Biljeznika iz ViseodredisniDelegatViseodredisniDelegat -= Biljeznik;

 // pozivamo 2 preostale metode ViseodredisniDelegat-aViseodredisniDelegat("Treći prosljeđeni niz znakova");

}}

Anonimne metode

Da bi skratili pisanje kôda, delegate možemo koristiti za kreiranje anonimnih metoda

U vs2008 imamo lambda operator koji još pojednostavljuje kreiranje anonimnih metoda

delegate int binOp(int x, int y); static void Main(string[] args) { binOp usp = delegate(int x, int y) { return x-y; }; }

Delegati i asinhrono pozivanje Osim sinhronog pozivanja funkcija, delegati nam omogućuju i

asinhrono pozivanje (što je objašenjno na kolegiju Distribuirani procesi - BeginInvoke) – kreira se novi thread koji izvršava metodu, a naš program nastavlja sa radom.

Rezultate asinhronog poziva možemo provjeriti sa EndInvoke

Događaji

Programi u grafičkim sučeljima moraju biti u stanji odgovarati na događaje

Događaj može biti pritisak na gumb, odabir opcije iz izbornika, događaj vremena i slično

U grafičkim sučeljima bilo koji objekt može pokrenuti događaj, a neki drugi objekt može biti zainterasiran za taj događaj. Tko će obraditi događaj nije bitno onome tko ga je pokrenuo

Kad neki objekt objavi događaj, svi objekti koji su pretplaćeni na taj događaj bivaju o tome obaviješteni

Događaji

U C# događaji se implementiraju pomoću delegata. Višeodredišni delegati nam omogućuju da se više objakata pretplati na neki događaj

Klasa izdavač definira delegat, a pretplatnička klasa koja se želi pretplatiti funkciju koja učahuri metodu koja će obrađivati događaj (event handler)

Prije kreiranja događaja, izdavač treba provjeriti je li itko prijavljan na događaj, jer ćemo u protivnom dobiti grešku

Događaji

Umjesto +=, za dodavanje novog preplatnika, mogli smo koristiti =, te bi prethodni pretplatnik mogao biti onda isključen, a delegat bi mogli pozvati i izravno

Zbog toga je ubačena ključna riječ event

Sada događaj može pokrenuti samo klasa koja ga je kreirala, te na njemu rade samo operatori += i -=

public event RukovateljPromjenomSekunde NaPromjenuSekunde;

Recommended