Upload
presley
View
37
Download
3
Embed Size (px)
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;