You are on page 1of 24

Visoka tehnika kola Ni

Studijski program:

Savremene raunarske tehnologije


.NET tehnologije

(11)

Obrada izuzetaka u C#-u


Prof. dr Zoran Velikovi, dipl. in. el.
Decembar, 2015.

Obrada izuzetaka (1)

IZUZECI (engl. exceptions) predstavljaju efikasan nain za obradu


greaka i drugih nedozvoljenih stanja.
Pod IZUZETKOM se moe podrazumevati OBJEKAT koji kapsulira
informacijue o neprihvatljivim pojavama u programu.
Ako se uklone SVE PROGRAMERSKE GREKE, ipak se mogu desiti
sistuacije koje se ne mogu izbei!
Primer opisane situacije je pokuaj otvaranja NEPOSTOJEEG
FAJLA ili NEDOSTATAK MEMORIJSKOG PROSTORA.
Dakle, ove situacije se nazivaju IZUZECI i nije ih mogue spreiti,
ali se mogu OBRADITI i tako omoguiti da se izvravanje programa
NE PREKINE.
Na pojavu ovakvih situacija, kae se da program baca izuzetak.

Obrada izuzetaka (2)

Pri pojavi izuzetaka ZAUSTAVLJA SE izvrenje TEKUE


INSTRUKCIJE i poziva se odgovarajua PROCEDURU ZA OBRADU
IZUZETKA.
Ako se u tekuoj funkciji nije predviena obrada izuzetka, onda e
CLR odmotati stek da bi se pronaao odgovarajuu proceduru za
obradu prekida.
Dakle, PROCEDURA ZA OBRADU IZUZETAKA treba da obradi
izuzetak i obezbediti NASTAVAK IZVRENJA PROGRAMA.
Naredba CATCH obezbeuje implementaciju procedure za obradu
izuzetaka.
Deo koda koji se mora izvriti iako se pojavio izuzetak stavlja se u
blok FINALLY.
Za ove potrebe koristi se klasa System.Exception ili klase izvedene
iz nje.

Naredba throw (1)

Imenski prostor System sadri sledee primere izuzetaka:


ArgumentNullException, InvalidCastException, OverflowException,
...
Izuzetak se baca da bi se ukazalo na nepredvieno stanje neke
klase.
Istovremeno formiranje objekta koji opisuje izuzetak i njegovo
bacanje se obavlja naredbom THROW i operatorom NEW:
throw new System.Exception();

Kada se baci izuzetak, a u tekuoj metodi nema odgovarajue


procedure, CLR odmotava stek i pregleda metode pozivaoce dok ne
pronae odgovarajuu koja moe obraditi izuzetak.
Ako CLR pregleda SVE FUNKCIJE (unazad) do metode Main, i ako ne
nae odgovarajuu metodu PREKIDA PROGRAM!

Naredba throw (2)


....
{ using System;
public class Test
Formiranje objekta t
tipa Test
{
public static void Main( )
{
Console.WriteLine("Enter Main...");
Test t = new Test( );
Poziv funkcije Func1()
t.Func1( );
objekta t
Console.WriteLine("Exit Main...");
}
Samo tampa tekst
public void Func1( )
{
Console.WriteLine("Enter Func1...");
Func2( );
Poziv funkcije Func2()
Console.WriteLine("Exit Func1..."); }

Naredba throw (3)


public void Func2( )
Funkcija Func2() baca
izuzetak.
{
Console.WriteLine("Enter Func2...");
throw new System.Exception( );
Console.WriteLine("Exit Func2...");
}
}
}

Bacanje izuzetka. Izazvae se problem


ako nema metode za obradu izuzetaka!

Output:
Enter Main...
Enter Func1...
Enter Func2...

Zato nema tampanja


izlaska iz Func1 i Func2?
Da li ima metode koja
e obraditi izuzetak?

Primer u VS 2008
Neobraeni izuzetak

Izuzetak
System.Exeption je
baen
Detalji na sledeem
slajdu

VS je prepoznao da NEMA METODE


za obradu baenog izuzetka!

Detalji o izuzetku i VS
Opis ovog
izuzetka

Svojstva
ovog
izuzetka

Uopte o svojstvima izuzetaka neto kasnije na ovom asu.

Naredba catch

Procedura za obradu izuzetaka se formira rezervisanom reju


CATCH.
Naredba THROW se izvrava u bloku TRY.
Prethodnom primeru je pridodata programska struktura TRAYCATCH u cilju hvatanja i obrade izuzetka.
Uobiajeno je da se potencijalno opasna naredba(e) (one koje mogu
izazvati prekide) stavlja(ju) u blok TRY.

Posle blokova TRY, postavljaju se naredbe CATCH.

TIP IZUZETKA koji se hvata specificira se u naredbi CATCH.

Ako NEMA SPECIFIKACIJE TIPA, onda je catch naredba


GENERIKA hvata SVE TIPOVE IZUZETAKA!
Pogledajte izmenjeni kod metode Func2(). ta se dobija ovom
izmenom?

Naredbe try-catch

Output:
Enter Main...
Enter Func1...
Enter Func2...
Entering try block...
Exception caught and
handled.
Exit Func2...
Exit Func1...
Exit Main...

public void Func2( )


{
Console.WriteLine( "Enter Func2..." );
try
{
Console.WriteLine( "Entering try block..." );
U try bloku se
throw new System.Exception( );
postavljaju
Console.WriteLine( "Exiting try block..." );
naredbe koje
mogu izazvati
}
Procedura za obradu izuzetaka se
izuzetka.
catch
formira rezervisanom reju catch.
{
Console.WriteLine( "Exception caught and handled." );
}
Console.WriteLine( "Exit Func2..." );
}

esto

korieni izuzeci

U C# je definisan veliki skup SISTEMSKIH IZUZETAKA.

Najee korieni izueci su prikazani u sledeoj tabeli:

IZUZETAK

OPIS

ArithmeticException

Osnovna klasa izuzetaka, bacaju ih aritmetiki


operatori.

DivideByZeroException

Bacaju se pri pokuaju deljenja nulom.

IndexOutOfRangeException

Bacaju se pri pokuaju pristupa nepostojeem


elementu niza.

InvalidCastException

Baca se pri pokuaju eksplicitne konverzije,


konverzija nije mogua.

OutOfMemoryException

Baca se pri neuspelom pokuaju alociranja


memorije operatorom new.

StackOverflowExceptin

Baca se kada stek poziva ima previe poziva


metoda koje tek treba kompajlirati.

Namenski izuzeci

Izuzetke treba koristiti tako da kada se desi problem, odmah treba


ponuditi NAIN NJEGOVOG REAVANJA:

Kad ponestane memorije;


Kada nema fajla koji se trai.

Treba ispisati bar poruku o greci (kako bi korisnik bio obaveten o


neregularnoj situaciji).
Pored GENERIKIH CATCH NAREDBI mogu se formirati i
NAMENSKE CATCH NAREDBE.
Shodno tome mogu se formirati i NAMENSKI IZUZECI!
Dozvoljeno je formiranje naredbi CATCH kojima se obrauju samo
ODGOVARAJUI TIPOVI IZUZETAKA.
Pokazaemo primere izuzetaka koji se javljaju prilikom pokuaja
deljenja nulom.
Takoe, razlikovaemo pokuaj deljenja nule sa nulom, kao specijalan
sluaj.

Namenski catch (1)


#region Using directives
using System;
using System.Collections.Generic;
using System.Text;
#endregion
namespace SpecifyingCaughtException
{
public class Test
{
public static void Main( )
{
Test t = new Test( );
t.TestFunc( );
}

Formiranje klase Test koja


poziva svoju metodu
TestFunc()

Namenski catch (2)


public void TestFunc( )
Generalno deljenje dva broja
moe proizvesti problem!
{
try
Pokuaj deljenja nulom moe
{
izazvati izuzetak obradi ga.
double a = 5;
double b = 0;
Console.WriteLine( "{0} / {1} = {2}", a, b, DoDivide(a, b) );
}
Hvataj prvo najei tip
1
catch ( System.DivideByZeroException )
izuzetaka pri deljenju
{
Console.WriteLine("DivideByZeroException caught!" );
}
2
catch ( System.ArithmeticException )
{
Console.WriteLine( "ArithmeticException caught!" );
}

Namenski catch (3)


3

catch

Izuzeci opte namene se hvataju tek na kraju

{
Console.WriteLine("Unknown exception caught" );
}
}
// deli samo ako je to dozvoljeno !

Bacanje dva tipa


izuzetka iz metode
DoDivide()

public double DoDivide(double a, double b)


{
if (b == 0)
1
throw new System.DivideByZeroException( );
if (a == 0)
2
throw new System.ArithmeticException( );
return a / b;
Output:
}
DivideByZeroException caught!
} }

Naredba finally (1)

DIREKTAN SKOK na metodu za obradu izuzetaka ponekad moe


izazvati probleme! Kada?
Ako program koristi neki resurs (otvara fajl) i on ostane zauzet
zbog skoka na metode za obradu izuzetaka eto problema! Koje vrste?
Da bi se specificirala akcija koja se mora obaviti PRE POZIVA
METODE za obradu izuzetaka, specificira se rezervisanom reju
finally.
Ova akcija se specificira u programskom bloku FINALLY.
ta vie, kod u bloku finally se izvrava BEZ OBZIRA da li je
izuzetak baen ili ne!

Naredba finally (2)


public void TestFunc( )
Pokuaj deljenja moe izazvati
{
izuzetak treba ga obarditi.
try
{
Console.WriteLine( Ovde se otvara fajl" );
double a = 5;
double b = 0;
Console.WriteLine("{0}/{1} = {2}", a, b, DoDivide(a, b));
Console.WriteLine( Ova linija moe ali i ne mora biti
tampana" );
}
try blok sa potencijano
opasnom naredbom.

Naredba finally (3)


// najei tip izuzetka
catch naredba sa
catch ( System.DivideByZeroException )
namenskim izuzetkom
{
Console.WriteLine("DivideByZeroException caught!" );
}
catch naredba sa
catch
generalizovanim izuzetkom
{
Console.WriteLine( "Unknown exception caught" );
}
Obavezno izvravanje bloka finally bez
obzira na to da li je izuzetak baen ili ne
finally
{
Console.WriteLine( Ovde zatvori ve otvoren fajl." );
}
}

Objekt tipa Exception (1)

U C# klasa System.Exception se koristi za opis izuzetaka.

Klasa System.Exception ima veliki broj svojstava:


SVOJSTVO

ZNAENJE

Message

Svojstvo Message predstavlja informacije o izuzetku i samo se


moe itati. Vrednost svojstva Message se definie prilikom
bacanja izuzetka i prosleuje se kao argument konstruktoru
izuzetka.

HelpLink

Svojstvo HelpLink predstavlja vezu do datoteke za pomo


povezanu sa izuzetkom.

StackTrace
Source
TargetSite

Svojstvo StackTrace je samo za itanje i sadri informaciju o


steku poziva za poruku o greci.
Svojstvo Source sadri ime programa koje koji je doveo do
izuzetka.
Svojstvo TagretSite sadri ime metode iz koje je baen
izuzetak.

Svojstva System.Exception (1)


...
namespace Programming_CSharp
{
using System;
public class Test
{
public static void Main( )
{
Test t = new Test( );
t.TestFunc( );
}
// pokuaj deljenja dva broja
// opsluivanje moguih izuzetaka
public void TestFunc( )
{

Korienje svojstava klase


System.Expection

Svojstva System.Exception (2)


try
{
Console.WriteLine( "Open file here" );
double a = 12;
double b = 0;
Console.WriteLine( "{0} / {1} = {2}", a, b, DoDivide(a, b) );
Console.WriteLine( "This line may or may not print" );
}
Svojstvo Message za objekt
e formiran izuzetkom
catch ( System.DivideByZeroException e )
{
Console.WriteLine( "\nDivideByZeroException! Msg: {0}", e.Message);
Console.WriteLine( "\nHelpLink: {0}", e.HelpLink);
Console.WriteLine( "\nHere's a stack trace: {0}\n", e.StackTrace);
}
Svojstvo HelpLink treba dodliti
pre ispaljivanja izuzetka.

Svojstvo StackTrace za
objekt e

Svojstva System.Exception (3)


catch
{
}
finally
{

Console.WriteLine("Unknown exception caught");

Console.WriteLine ("Close file here.");


} } // kraj Test
Svojstvo Message nije zadato te se

// deli ako je to mogue!


public double DoDivide(double a, double b)
{
if (b == 0)
{

poziva standardna poruka ovog izuzetka:


Attempted to devide by zero.
Formiranje objekta e tipa
DivideByZeroException.

DivideByZeroException e = new DivideByZeroException( );


e.HelpLink ="http://www.libertyassociates.com";
throw e;
Svojstvo HelpLink se dodeljuje pre
ispaljivanja izuzetka.
Bacanje izuzetka

Svojstva System.Exception (4)


if (a == 0)
throw new ArithmeticException( );
return a/b;
Bacanje izuzetka
}
}
}

Output:
Open file here
DivideByZeroException! Msg: Attempted to divide by zero.
HelpLink: http://www.libertyassociates.com
Here's a stack trace:
at Programming_CSharp.Test.DoDivide(Double a, Double b)
in c:\...exception06.cs:line 56
at Programming_CSharp.Test.TestFunc( )
in...exception06.cs:line 22
Close file here.

Sopstveni izuzeci

Ponekad je korisno napisati SOPSTVENE (namenske) IZUZETKE.


Sopstveni izuzetak treba izvesti iz klase
System.ApplicationException.
Nasleivanje klase
ApplicationException

namespace CustomExceptions
{

public class MyCustomException : System.ApplicationException


{
public MyCustomException(string message):
base(message)

Konstruktor

{
}
} ...

Isto to i this, koristi se za pristup lanu


osnovne klase iz izvedene klase.

String argument koji se


prosleuje svojoj klasi.

You might also like